目录
一、前言二、通过Setter方法配置Bean
三、通过构造器配置Bean
  1. 通过属性名配置
  2. 通过索引配置
  3. 通过属性类型配置
四、通过p命名空间配置bean
五、引用/注入其他bean对象
六、引用/注入内部bean对象
七、引入/注入集合/数组类型
八、使用util名称空间
九、级联赋值


相关文章

【Spring(一)】如何获取对象(Bean)

【Spring(一)】如何获取对象(Bean)

一、前言

 上一篇文章中,我们对Spring做了一些基本的了解,以及在Spring中如何获取Bean。我们在XML配置文件中,只是写了那些标签和属性,但它们都各自代表什么、如何配置一个Bean、Bean的配置方式等,这些都是我们接下来需要了解和学习的。

 在配置Bean的时候,我们首先得知道需要配置的那个类是什么。这就和我们用传统方式创建对象一样,通过类来创建一个对象。我们在下边的示例中都使用这个Monster类讲解。

package com.jl.spring.bean;

/**
 * @author long
 * @date 2022/8/30
 */
public class Monster {
    private Integer monsterId;
    private String name;
    private String skill;
    public Monster(){}
    public Monster(Integer monsterId, String name, String skill) {
        this.monsterId = monsterId;
        this.name = name;
        this.skill = skill;
    }

    public Integer getMonsterId() {
        return monsterId;
    }

    public void setMonsterId(Integer monsterId) {
        this.monsterId = monsterId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "monsterId=" + monsterId +
                ", name='" + name + '\'' +
                ", skill='" + skill + '\'' +
                '}';
    }
}

二、通过Setter方法配置Bean

<bean class="com.jl.spring.bean.Monster" id="monster01">
    <property name="monsterId" value="100"/>
    <property name="name" value="牛魔王"/>
    <property name="skill" value="芭蕉扇"/>
</bean>
  1. class是类的全路径,通过类的全路径我们的Spring容器才可以创建Bean对象。
  2. id是Bean的名称,我们可以通过id值来获取到这个Bean对象。
  3. property这个标签用来标识这是一个属性。
  4. name是属性的名称(我们的name值必须要和对象中的属性名一致)。
  5. value是属性的值。

在上边的配置中,我们属性配置用的都是property这个标签,而这个使用这个标签装配属性的前提是:我们的类必须提供相应的setter方法无参构造方法

⚠如果我们不提供属性相应的setter(),那么就会出现下边的错误:

java 对象首位添加_java


⚠如果不提供无参构造方法就会出现如下的错误:

java 对象首位添加_后端_02

三、通过构造器配置Bean

通过构造器配置器的一个前提就是:提供有参构造。不提供就会报错。
通过构造器来配置Bean,一共有三种配置方式:通过属性名配置、通过索引来配置、通过类型来配置。

1. 通过属性名配置

<bean class="com.jl.spring.bean.Monster" id="monster02">
		<constructor-arg name="monsterId" value="100"/>
		<constructor-arg name="name" value="牛魔王"/>
		<constructor-arg name="skill" value="芭蕉扇"/>
</bean>

这种方式和使用Setter()方式来配置差不多,唯一的区别就是:我们使用有参构造来配置Bean使用的标签是<constructor-arg>

2. 通过索引配置

<bean class="com.jl.spring.bean.Monster" id="monster02">
      <constructor-arg value="200" index="0"/>
      <constructor-arg value="白骨精" index="1"/>
      <constructor-arg value="九阴白骨爪" index="2"/>
</bean>

使用索引配置Bean需要在<constructor-arg>使用index属性,index从0开始,对应我们有参构造函数中参数的顺序。

3. 通过属性类型配置

<bean class="com.jl.spring.bean.Monster"  id="monster02">
    <constructor-arg value="200" type="java.lang.Integer"/>
    <constructor-arg value="白骨精" type="java.lang.String"/>
    <constructor-arg value="九阴白骨爪" type="java.lang.String"/>
</bean>

之所以可以使用类型配置Bean,是因为Java中的重载中规定:不能有完全相同的属性类型。

四、通过p命名空间配置bean

这种方式,同样也要求类必须具备Setter()和无参构造这两个条件。

在使用P命名空间前还需要再XML配置文件的头部添加相关的声明。xmlns:p="http://www.springframework.org/schema/p

java 对象首位添加_spring_03

<!--通过p命名空间来配置-->
<bean id="monster03" class="com.jl.spring.bean.Monster"
     p:monsterId="500"
     p:name="红孩儿"
     p:skill="喷火"
/>

我们的这种方式,配置的时候是写在标签内的,而不是在标签体中。

五、引用/注入其他bean对象

我们在上边的学习的过程,属性都是基本数据类型的。但我们的使用过程中,一个对象的属性还有可能是其他我们自定义的对象类型。例如:Service调用Dao的时候,需要在Service层创建一个Dao对象。我们这里就讲解这种情况如何取解决。

当然,开始之前我们也得有两个类,来演示。

package com.jl.spring.dao;

/**
 * @author long
 * @date 2022/8/31
 */
public class MemberDAOImpl {
    public MemberDAOImpl(){
        System.out.println("MemberDAOImpl构造器被调用....");
    }
    public void add(){
        System.out.println("add方法被调用....");
    }
}
package com.jl.spring.service;

import com.jl.spring.dao.MemberDAOImpl;

/**
 * @author long
 * @date 2022/8/31
 */
public class MemberServiceImpl {
    private MemberDAOImpl memberDAO;
    public MemberDAOImpl getMemberDAO(){
        return memberDAO;
    }

    public void setMemberDAO(MemberDAOImpl memberDAO) {
        this.memberDAO = memberDAO;
    }

    public void add(){
        System.out.println("MemberServiceImpl add() 被调用....");
        memberDAO.add();
    }
}

测试类

@Test
public void setBeanByRef(){
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
    MemberServiceImpl memberService = ioc.getBean("memberService", MemberServiceImpl.class);
    memberService.add();
}
<!--配置MemberDAOImpl对象-->
<bean class="com.jl.spring.dao.MemberDAOImpl" id="memberDAO"/>
    <!--配置MemberServiceImpl对象-->
<bean class="com.jl.spring.service.MemberServiceImpl" id="memberService">
      <property name="memberDAO" ref="memberDAO"/>
</bean>

property标签中的name和我们前边一样,都是属性的名称。但因为属性值是对象,所以我们这里使用relrel的值是引用的对象,而且这个值是引用的对象的id值。

 这里说明的一点:我们没有要求必须要将引用对象的配置写到前边,因为Spring是在创建好对象之后才进行属性装配的。不知道我这里有没有说清楚,贴一张图吧:

java 对象首位添加_java 对象首位添加_04


最后的运行结果:

java 对象首位添加_后端_05

六、引用/注入内部bean对象

 这里的内容和【五】一样都是属性为对象的时候的一种处理。但这里使用的是内部注入的方式。

类全部都一样,不同的就是配置方式的区别。

<!--使用内部bean的方式来配置MemberServiceImpl-->
<bean class="com.jl.spring.service.MemberServiceImpl" id="memberService">
   <property name="memberDAO">
       <bean class="com.jl.spring.dao.MemberDAOImpl"></bean>
   </property>
</bean>

这种内部注入的方式,是在property 标签体内,直接使用bean标签来配置的。因为只是内部使用这个对象,所以可以只写个class全类名就行。

七、引入/注入集合/数组类型

我们这里通过一个Master来讲解不同的集合类型。

package com.jl.spring.bean;

import java.util.*;

/**
 * @author long
 * @date 2022/8/31
 */
public class Master {
    private String name;
    private List<Monster> monsterList;
    private Map<String,Monster> monsterMap;
    private Set<Monster> monsterSet;
    private String[] monsterName;
    private Properties pros;

    @Override
    public String toString() {
        return "Master{" +
                "name='" + name + '\'' +
                ", monsterList=" + monsterList +
                ", monsterMap=" + monsterMap +
                ", monsterSet=" + monsterSet +
                ", monsterName=" + Arrays.toString(monsterName) +
                ", pros=" + pros +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Monster> getMonsterList() {
        return monsterList;
    }

    public void setMonsterList(List<Monster> monsterList) {
        this.monsterList = monsterList;
    }

    public Map<String, Monster> getMonsterMap() {
        return monsterMap;
    }

    public void setMonsterMap(Map<String, Monster> monsterMap) {
        this.monsterMap = monsterMap;
    }

    public Set<Monster> getMonsterSet() {
        return monsterSet;
    }

    public void setMonsterSet(Set<Monster> monsterSet) {
        this.monsterSet = monsterSet;
    }

    public String[] getMonsterName() {
        return monsterName;
    }

    public void setMonsterName(String[] monsterName) {
        this.monsterName = monsterName;
    }

    public Properties getPros() {
        return pros;
    }

    public void setPros(Properties pros) {
        this.pros = pros;
    }
}
<!--配置Master对象,给集合属性赋值-->
<bean class="com.jl.spring.bean.Master" id="master">
   <property name="name" value="太上老君"/>
   <!--list集合-->
   <property name="monsterList">
       <list>
           <!--引用的方式-->
           <ref bean="monster01"/>
           <ref bean="monster02"/>
           <!--内部bean的方式-->
           <bean class="com.jl.spring.bean.Monster">
               <property name="name" value="葫芦娃"/>
               <property name="skill" value="喷水"/>
               <property name="monsterId" value="111"/>
           </bean>
       </list>
   </property>
   <!--map集合-->
   <property name="monsterMap">
       <map>
           <entry>
               <key>
                   <value>monster02</value>
               </key>
               <ref bean="monster02"></ref>
           </entry>
           <entry>
               <key>
                   <value>monster03</value>
               </key>
               <ref bean="monster03"/>
           </entry>
       </map>
   </property>
   <!--set集合-->
   <property name="monsterSet">
       <set>
           <ref bean="monster01"/>
           <ref bean="monster02"/>
           <bean class="com.jl.spring.bean.Monster">
               <property name="monsterId" value="123"/>
               <property name="name" value="银角大王"/>
               <property name="skill" value="扔葫芦"/>
           </bean>
       </set>
   </property>
   <!--给数组注入-->
   <property name="monsterName">
       <array>
           <value>123</value>
           <value>321</value>
           <value>456</value>
           <value>654</value>
       </array>
   </property>
   <!--配置properties-->
   <property name="pros">
       <props>
           <prop key="key01">one</prop>
           <prop key="key02">two</prop>
           <prop key="key03">three</prop>
       </props>
   </property>
</bean>

这里面的PropertiesHashtable的子类 , 是 key-value 的形式(key和value都是String)。

测试类

@Test
public void setBeanByCollection(){
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
    Master master = ioc.getBean("master", Master.class);
    System.out.println(master);
}

结果截图

java 对象首位添加_spring_06

八、使用util名称空间

和p命名空间一样我们同样需要在XML文件的头部添加声明xmlns:util="http://www.springframework.org/schema/util"

java 对象首位添加_java_07


我们这里同样使用Matser类说明。

<!--通过util命名空间配置-->
<util:list id="myList">
    <ref bean="monster01"/>
    <ref bean="monster02"/>
    <ref bean="monster03"/>
</util:list>
<bean id="monster07" class="com.jl.spring.bean.Master">
    <property name="monsterList" ref="myList"/>
</bean>

测试代码

@Test
public void  setBeanByUtil(){
     ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
     Master master = ioc.getBean("monster07", Master.class);
     System.out.println(master);
 }

运行截图

java 对象首位添加_后端_08


因为我们这里只注入了monsterList属性,所以其他的属性都为null。当然util除了可以注入List,还可以注入其他的集合属性。

java 对象首位添加_spring_09

九、级联赋值

级联赋值,从他这个名字就可以看出:它是属性的多级关联赋值。不懂也没有关系,我们下边会举例说明。

首先我们的准备两个类:DeptEmp

package com.jl.spring.bean;

/**
 * @author Long
 * @date 2022/11/19
 * @CSDN 
 **/
public class Emp {
    private String name;
    private Dept dept;

    public Emp() {
    }

    public Emp(String name, Dept dept) {
        this.name = name;
        this.dept = dept;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "name='" + name + '\'' +
                ", dept=" + dept +
                '}';
    }
}
package com.jl.spring.bean;

/**
 * @author Long
 * @date 2022/11/19
 * @CSDN 
 **/
public class Dept {
    private String name;
    public Dept() {
    }
    public Dept(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "name='" + name + '\'' +
                '}';
    }
}
<bean id="emp" class="com.jl.spring.bean.Emp">
    <property name="name" value="jack"/>
    <property name="dept" ref="dept"/>
    <property name="dept.name" value="Java 开发部"/>
</bean>
<bean id="dept" class="com.jl.spring.beans.Dept"/>

我们可以通过在引用对象之后给引用的对象的属性进行赋值。这样方式就叫级联赋值

测试类

@Test
public void  setBeanByCascadingValues(){
   ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
   Emp emp = ioc.getBean("emp", Emp.class);
   System.out.println(emp);
}

结果截图

java 对象首位添加_java 对象首位添加_10