Spring DI详解

一、Dependency Injection: 依赖注入

  • Ioc:作用是把对象的创建权,反转到Spring,让Spring容器来管理
  • DI:作用是Spring创建对象的过程中,将对象依赖属性通过配置进行注入

二、自动装配注入

autowire属性:让spring按照一定的方式自己去找合适的对象,并完成DI

- default:不要自动注入
- no:不要自动注入
- byName:按照名字注入(按照属性的名字在spring中找bean) factory.getBean("属性的名字")
- byType:按照依赖对象的类型注入(factory.getBean(属性的类型))
- constructor:按照对象的构造器上面的参数类型注入
注意:
1,如果按照byName自动注入,要求所有的属性名字和id的名字必须保证一种规范的命名方式;
2,如果按照byType注入,如果spring中同一个类型有多个实例-->报bean不是唯一类型错误;
  • AutoBean
package com.revanwang.autowire;


import lombok.Data;

@Data
public class AutoBean {

}
  • AutoWireBean
package com.revanwang.autowire;

public class AutoWireBean {
    private AutoBean autoBean;

    public void setAutoBean(AutoBean bean) {
        this.autoBean = bean;
    }

    public void sayAutoWireBean() {
        System.out.println("AutoBean:==" + this.autoBean);
    }
}
  • autoBean.xml
<?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">

    <!--
        autowire属性:让Spring按照一定的方式自己去找合适的对象,并完成DI
            - default:不要自动注入
            - no     :不要自动注入
            - byName :按照名字注入(按照属性的名字在Spring中找bean)factory.getBean("属性的名字")
            - byType :按照依赖对象的类型注入(factory.getBean(属性的类型))
            - constructor :按照对象的构造器上面的参数类型注入
    -->
    <bean id="auto" class="com.revanwang.autowire.AutoBean"/>
    <bean id="autoBean" class="com.revanwang.autowire.AutoWireBean" autowire="byType"/>

</beans>

三、setter方法注入

1、使用setter注入:

1:使用bean元素的子元素设置;

  • 1,简单类型值,直接使用value赋值;
  • 2,引用类型,使用ref赋值;
  • 3,集合类型,直接使用对应的集合类型元素即可。

2:spring通过属性的setter方法注入值;

3:在配置文件中配置的值都是string,spring可以自动的完成类型的转换

4:属性的设置值是在init方法执行之前完成的

5:改进spring的测试,直接在测试类里面注入需要测试的对象

set方法注入简单类型、集合类型、对象类型

  • Address
package com.revanwang.setter;

import lombok.Data;

@Data
public class Address {
    private String  id;
    private String  name;

    public Address() {}

    public Address(String id, String name) {
        this.id = id;
        this.name = name;
    }
}
  • Employee
package com.revanwang.setter;

import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@Data
public class Employee {
    private Long    id;
    private String  name;
    private Set<String>     emailSet;
    private List<String>    emailList;
    private String[]        emailArray;
    private Map<String, Object> map;
    private Properties      ppts;

    private Address         address;
}
  • employee.xml
<?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">


    <!-- 通过构造器给Address注入值 -->
    <bean id="address" class="com.revanwang.setter.Address">
        <constructor-arg name="id" value="11"/>
        <constructor-arg name="name" value="Revan"/>
    </bean>

    <bean id="employee" class="com.revanwang.setter.Employee">
        <property name="id" value="28"/>
        <property name="name" value="Revan"/>
        <property name="emailSet">
            <set>
                <value>emailSet1</value>
                <value>emailSet2</value>
                <value>emailSet3</value>
            </set>
        </property>

        <property name="emailArray">
            <array>
                <value>emailArray1</value>
                <value>emailArray2</value>
                <value>emailArray3</value>
            </array>
        </property>

        <property name="emailList">
            <list>
                <value>emailList1</value>
                <value>emailList2</value>
                <value>emailList3</value>
            </list>
        </property>

        <property name="map">
            <map>
                <entry key="k1" value="v1"/>
                <entry key="k2" value="v2"/>
                <entry key="k3" value="v3"/>
            </map>
        </property>

        <property name="ppts">
            <props>
                <prop key="p1">pV1</prop>
                <prop key="p2">pV2</prop>
                <prop key="p3">pV3</prop>
            </props>
        </property>

        <property name="address" ref="address"/>

    </bean>

</beans>

四、构造器注入

1、constructor-arg:构造器参数

  • 1:spring在实例化对象的时候,如果对象没有配置constructor-arg,则使用默认的构造器实例化对象
  • 2:如果有constructor-arg,那么spring使用这些constructor-arg来唯一确定一个构造器

1.1,默认情况下,constructor-arg的顺序就是构造器参数的顺序

  • 1.index:在构造器中的参数位置
  • 2.type:在构造器中的参数的类型
  • 3.name:在构造器中按照构造器的参数名字设置值

构造器示例

  • Address
package com.revanwang.constructor;

import lombok.Data;

@Data
public class Address {

    private Long    id;
    private String  name;
}
  • User
package com.revanwang.constructor;


public class User {

    private Long    id;
    private String  name;

    private Address address;


    public User(Long id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}
  • constructor.xml
<?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="address" class="com.revanwang.constructor.Address">
        <property name="id" value="11"/>
        <property name="name" value="Revan"/>
    </bean>

    <bean id="user" class="com.revanwang.constructor.User">
        <constructor-arg name="id" value="1"/>
        <constructor-arg name="name" value="WRW"/>
        <constructor-arg name="address" ref="address"/>
    </bean>

</beans>

五、Spring 表达式语言

通过setter / 构造器给bean注入的值都是静态定义的,若要为属性动态装配值时,只能使用Spring表达式语言

Spring特点

    1. 使用bean的id来引用bean
    1. 调用方法和访问对象的属性
    1. 对值进行算术,关系和逻辑运算
    1. 正则表达式匹配
    1. 集合操作
  • SP
package com.revanwang.spel;

import lombok.Data;

@Data
public class SP {
    private Long    id;
    private String  name;
}
  • SPEL
package com.revanwang.spel;

import lombok.Data;

@Data
public class SPEL {
    private Long    id;
    private String  name;

}
  • spel.xml
<?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 name="sp" class="com.revanwang.spel.SP">
        <property name="id" value="111"/>
        <property name="name" value="Revan"/>
    </bean>

    <bean name="spel" class="com.revanwang.spel.SPEL">
        <property name="id" value="#{11}"/>
        <property name="name" value="#{sp.name}"/>
    </bean>

</beans>

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!