一、设值注入

设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

构建两个Bean:

public class School {
    private String name;

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

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class Student {
    private String username;
    private String password;
    private School school;

    public void setSchool(School school) {
        this.school = school;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", school=" + school +
                '}';
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="school" class="cn.lwb.spring.setterInject.School">
        <property name="name" value="sichuan"/>
    </bean>

    <bean id="student" class="cn.lwb.spring.setterInject.Student">
        <property name="username" value="lwb" />
        <property name="password" value="520" />
        <property name="school" ref="school"/>
    </bean>

</beans>
@org.junit.Test
    public void test1() {
        String config = "cn/lwb/spring/setterInject/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
        Student student = (Student) applicationContext.getBean("student");
        System.out.println(student);
    }

输出结果:

java static类注入bean bean注入一个类对象_spring

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。 ref的值必须为某 bean 的 id 值。

二、构造注入

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。

public Student(String username, String password, School school) {
        this.username = username;
        this.password = password;
        this.school = school;
    }
<!--构造器注入,索引注入-->
    <bean id="student1" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg index="0" value="lwb"/>
        <constructor-arg index="1" value="520" />
        <constructor-arg index="2" ref="school"/>
    </bean>

    <!--注入顺序必须与构造器中参数的顺序一致-->
    <bean id="student2" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg value="lwb"/>
        <constructor-arg value="520" />
        <constructor-arg ref="school"/>
    </bean>

    <!--根据构造器参数名称注入-->
    <bean id="student3" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg name="username" value="lwb"/>
        <constructor-arg name="password" value="520" />
        <constructor-arg name="school" ref="school"/>
    </bean>

三、命名空间注入

对于设值注入与构造注入,在配置文件中,除了使用<property/>或<constructor-arg/>标签外,还可使用命名空间注入的方式,让注入的以<bean/>标签属性的方式出现。根据注入实现方式的不同,分为 p 命名空间注入与 c 命名空间注入。
p 命名空间注入:采用设值注入方式,故需要有相应的 setter
c 命名空间注入:采用构造注入方式,故需要有相应的构造器

  1. p 命名空间设值注入

p命名空间设值注入,引入命名空间约束:xmlns:p="http://www.springframework.org/schema/p",在文档中搜索p:name,便可以找到文档例子

java static类注入bean bean注入一个类对象_命名空间_02

2. C命名空间构造注入

依然在文档中搜索,可以找到例子:

java static类注入bean bean注入一个类对象_命名空间_03

四、集合属性注入

java static类注入bean bean注入一个类对象_xml_04

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean id="school1" class="cn.lwb.spring.connectionInject.School" p:name="清华大学"/>
        <bean id="school2" class="cn.lwb.spring.connectionInject.School" p:name="北京大学"/>

        <bean id="student" class="cn.lwb.spring.connectionInject.Student">
            <property name="myMap">
                <map>
                    <entry key="张三" value="18"/>
                    <entry key="李四" value="18"/>
                    <entry key="王五" value="18"/>
                </map>
            </property>
            <property name="myList">
                <list>
                    <ref bean="school1"/>
                    <ref bean="school2"/>
                </list>
            </property>
            <property name="myPro">
                <props>
                    <prop key="name">lwb</prop>
                    <prop key="age">18</prop>
                </props>
            </property>
            <property name="mySet">
                <set>
                    <value>清华</value>
                    <value>北大</value>
                </set>
            </property>
            <property name="myStrs">
                <array>
                    <value>中国</value>
                    <value>四川</value>
                    <value>成都</value>
                </array>
            </property>
        </bean>
</beans>

其中值为简单属性的Set/List/Array可以用简写的方式:

<property name="mySet" value="清华,北大" />
<property name="myStrs" value="中国,四川,成都" />

五、对于域属性的自动注入

对于域属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置autowire 属性值,为域属性进行隐式自动注入。根据自动注入判断标准的不同,可以分为两种:

byName:根据名称自动注入
byType:根据类型自动注入
1、byName 方式自动注入

当配置文件中被调用者 Bean 的 id 值与代码中调用者 Bean 类的属性名相同时,可使用byName 方式,让容器自动将被调用者 Bean 注入给调用者 Bean。容器是通过调用者的 Bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

java static类注入bean bean注入一个类对象_命名空间_05


2、byType 方式自动注入

使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 Bean 类的某域属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

六、SPEL

spring可以通过SPEL表达式来注入值,同时也可以使用一个Bean调用另一个Bean的方法来注入值:

public class Person {

    private String pusernmae;
    private int page;

    public String getPusernmae() {
        return pusernmae;
    }

    public void setPusernmae(String pusernmae) {
        this.pusernmae = pusernmae;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    @Override
    public String toString() {
        return "Person{" +
                "pusernmae='" + pusernmae + '\'' +
                ", page='" + page + '\'' +
                '}';
    }

    public int getAge() {
        return page > 20 ? 20 : page;
    }
}
public class Student {

    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
<bean id="person" class="cn.lwb.spring.SPEL.Person">
        <property name="page" value="#{T(java.lang.Math).random() * 50}" />
        <property name="pusernmae" value="张三" />
    </bean>

    <bean id="student" class="cn.lwb.spring.SPEL.Student">
        <property name="username" value="王五" />
        <!--<property name="age" value="#{person.page > 25 ? 20 : person.page}"/>-->
        <property name="age" value="#{person.getAge()}"/>
    </bean>

由上面的xml配置可以看见,SPEL既可以通过java函数表达式来注入值,也可以通过调用别的Bean的方法或者属性来给自己注入值。