目录

一、什么是依赖注入

简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值。

二、DI_依赖注入三种方式

1.Setter注入

2.构造方法注入

3.自动注入

自动注入有两种配置方式:

autowire的取值如下:

测试自动注入:

三、DI_依赖注入类型

1.在被注入类中编写需要注入的属性名及类型

2.测试方法

3.在xml文件中编写注入代码

(1)注入bean类型:private StudentDao studentDao;

(2)注入基本数据类型:private String name; //字符串类型                                          private int count; //基本数据类型

(3)注入List集合:private List names; // 字符串类型List集合                                 private List students1; // 对象类型List集合

(4)注入Set集合:private Set students2; // 对象类型Set集合

(5)注入Map集合:    private Map names2; //字符串类型Map集合                                     private Map students3;// 对象类型Map集合,student>,string>

(6)注入Properties对象:private Properties properties;//Properties类型


一、什么是依赖注入

spring 动态注入内存释放 springdi注入_java

依赖注入(Dependency Injection,简称DI),它是Spring控制反转思想的具体实现。

控制反转将对象的创建交给了 Spring ,但是对象中可能会依赖其他对象。比如service 类中要有 dao 类的属性,我们称 service 依赖于dao。之前需要手动注入属性值,代码如下:

public interface StudentDao {
   Student findById(int id);
 }

 
 public class StudentDaoImpl implements StudentDao{ 
    @Override
    public Student findById(int id) {
        // 模拟根据id查询学生
        return new Student(1,"百战程序员","北京");
   }
 }public class StudentService {
// service依赖dao,手动注入属性值,即手动维护依赖关系
    private StudentDao studentDao = new StudentDaoImpl();
    public Student findStudentById(int id){
        return studentDao.findById(id);
   }
}

此时,当 StudentService 的想要使用 StudentDao 的另一个实现类如StudentDaoImpl2时,则需要修改 Java 源码,造成代码的可维护性降低。

而使用 Spring 框架后, Spring 管理 Service 对象与 Dao 对象,此时它能够为Service 对象注入依赖的 Dao 属性值。这就是 Spring 的依赖注入。

简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值。

二、DI_依赖注入三种方式

spring 动态注入内存释放 springdi注入_List_02

 在之前的开发中,可以通过setter方法或构造方法设置对象的属性值,在Spring框架中,我们可以通过调用setter方法或构造方法给属性赋值。

1.Setter注入

(1)被注入类编写属性的setter方法:(setter注入需要在类中编写setter方法)

public class StudentService {
    private StudentDao studentDao;
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
   }
}

(2)配置文件中,给需要注入属性值的<bean>中设置<property>

<bean>:配置对象          <property>通过setter方法注入    <constructor-arg>通过构造器注入
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
        <bean id="studentService" class="com.itbaizhan.service.StudentService">
                <!--依赖注入-->
                <!--property:专门用于setter注入标签  name:StudentService类中的属性名   ref:容器中对象的id值-->
                <property name="studentDao" ref="studentDao"></property>
         </bean>

(3)测试是否注入成功

public class TestContainer {
    @Test
    public void t1(){
//        创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//        从容器中获取对象
        StudentService studentService = (StudentService) ac.getBean("studentService");
        System.out.println(studentService);
        System.out.println(studentService.getStudentDao());
        System.out.println(studentService.findStudentById(1));
    }
}

(4)测试结果

spring 动态注入内存释放 springdi注入_spring_03

标明注入成功! 

2.构造方法注入

(1)被注入类编写有参的构造方法:(构造方法注入需要在类中编写构造方法)

public class StudentService {
    private StudentDao studentDao;
    public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;
   }
}

(2)给需要注入属性值的<bean>中设置<constructor-arg>

<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
        <bean id="studentService" class="com.itbaizhan.service.StudentService">
                <!--依赖注入-->
                <!--constructor-arg:专门用于构造方法注入标签  name:StudentService类中的属性名   ref:容器中对象的id值-->
                <constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
        </bean>

(3)测试是否注入成功、测试结果 如setter注入一样

3.自动注入

spring 动态注入内存释放 springdi注入_java_04

自动注入不需要在 <bean> 标签中添加其他标签注入属性值,而是自动从容器中找到相应的bean对象设置为属性值。

自动注入有两种配置方式:

1.全局配置:在 <beans> 中设置 default - autowire 属性可以定义 所有 bean 对象的自动注入策略。(一般不使用)

2.局部配置:在 <bean> 中设置 autowire 属性可以定义 当前 bean 对象的自动注入策略。(一般使用)

autowire的取值如下:

no 不会进行自动注入。

default 全局配置 default 相当于 no ,局部配置 default 表示使用全局配置

byName 在 Spring 容器中查找 id 与属性名相同的 bean ,并进行注入。需要提供 set 方法。

byType 在 Spring 容器中查找类型与属性类型相同的 bean ,并进行注入。需要提供 set 方

法。

constructor 在 Spring 容器中查找 id 与属性名相同的 bean ,并进行注入。需要提供构造方

法。

测试自动注入:

1.为依赖的对象提供setter和构造方法

public class StudentService {
    // 依赖
    private StudentDao studentDao;
    // 构造方法
    public StudentService() {
   }
    
    public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;
   }
    // setter方法
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
   }
    // 调用依赖的方法
    public Student findStudentById(int id) {
        return studentDao.findById(id);
   }
}

2.配置自动注入:

(1)配置局部自动注入

<!-- 根据beanId等于属性名自动注入 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService" autowire="byName"></bean><!-- 根据bean类型等于属性类型自动注入 -->
 <bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>  
<bean id="studentService"class="com.itbaizhan.service.StudentService" autowire="byType"></bean><!-- 利用构造方法自动注入 -->
 <bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>  
<bean id="studentService"class="com.itbaizhan.service.StudentService" autowire="constructor"></bean>

(2)配置全局自动注入

<?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"
default-autowire="constructor">

三、DI_依赖注入类型

spring 动态注入内存释放 springdi注入_spring 动态注入内存释放_05

 DI支持注入bean类型、基本数据类型和字符串、List集合、Set集合、Map集合、Properties对象类型等,他们的写法如下:

1.在被注入类中编写需要注入的属性名及类型

public class StudentService {
    private StudentDao studentDao;//bean类型
    private String name; //字符串类型
    private int count; //基本数据类型
    private List<String> names; // 字符串类型List集合
    private List<Student> students1; // 对象类型List集合
    private Set<Student> students2; // 对象类型Set集合
    private Map<String,String> names2; //字符串类型Map集合
    private Map<String,Student> students3;// 对象类型Map集合
    private Properties properties;//Properties类型
     // 省略getter/setter/toString
}

2.测试方法

@Test
    public void t3(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
        StudentService studentService = (StudentService)ac.getBean("studentService");
        System.out.println(studentService);
    }

3.在xml文件中编写注入代码

(1)注入bean类型:private StudentDao studentDao;

写法一:

<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
    <bean id="studentService" class="com.itbaizhan.service.StudentService">
        <!--注入bean写法一:-->
        <property name="studentDao" ref="studentDao"></property>
</bean>

写法二:

<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService">
     <!--注入bean写法二:-->
     <property name="studentDao">
            <ref bean="studentDao"></ref>
     </property>
</bean>

(2)注入基本数据类型:private String name; //字符串类型
                                          private int count; //基本数据类型

<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入基本数据类型和字符串,写法一:name:属性名   value:属性值-->
        <property name="name" value="写法"></property>
        
        <!--注入基本数据类型和字符串,写法二:name:属性名   value:属性值-->
        <property name="count">
            <value>10</value>
        </property>
</bean>

(3)注入List集合:private List<String> names; // 字符串类型List集合
                                 private List<Student> students1; // 对象类型List集合

注入简单数据类型List集合:private List<String> names;

<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入基本数据类型和字符串,写法一:name:属性名   value:属性值-->
        <property name="name" value="写法"></property>
        
        <!--注入基本数据类型和字符串,写法二:name:属性名   value:属性值-->
        <property name="count">
            <value>10</value>
        </property>
</bean>

注入对象类型List集合:private List<Student> students1; 

<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象类型List集合,name:属性名  bean:对象-->
        <property name="students1">
            <list>
                <bean class="com.itbaizhan.domain.Student">
                    <property name="id" value="1"></property>
                    <property name="name" value="程序员1"></property>
                    <property name="address" value="北京"></property>
                </bean>
                <bean class="com.itbaizhan.domain.Student">
                    <property name="id" value="2"></property>
                    <property name="name" value="程序员2"></property>
                    <property name="address" value="上海"></property>
                </bean>
            </list>
        </property>
</bean>

(4)注入Set集合:private Set<Student> students2; // 对象类型Set集合

注入Set集合和List集合大体一样,只是把<List>标签换成<Set>标签

<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象类型Set集合,name:属性名  bean:对象-->
        <property name="students2">
            <set>
                <bean class="com.itbaizhan.domain.Student">
                    <property name="id" value="3"></property>
                    <property name="name" value="程序员3"></property>
                    <property name="address" value="北京"></property>
                </bean>
                <bean class="com.itbaizhan.domain.Student">
                    <property name="id" value="4"></property>
                    <property name="name" value="程序员4"></property>
                    <property name="address" value="上海"></property>
                </bean>
            </set>
        </property>
</bean>

(5)注入Map集合:private Map<String,String> names2; //字符串类型Map集合
                                 private Map<String,Student> students3;// 对象类型Map集合

注入简单数据类型Map集合:

private Map<String,String> names2;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入简单数据类型Map集合-->
        <property name="names2">
            <map>
                <entry key="student1" value="bz"></entry>
                <entry key="student2" value="sxt"></entry>
            </map>
        </property>
</bean>

注入对象数据类型Map集合:

private Map<String,Student> students3;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象数据类型Map集合,value-ref:引入定义好的对象值的id值-->
        <property name="students3">
            <map>
                <entry key="student1" value-ref="s1"></entry>
                <entry key="student2" value-ref="s2"></entry>
            </map>
        </property>
</bean>

<bean id="s1" class="com.itbaizhan.domain.Student">
        <property name="id" value="1"></property>
        <property name="name" value="bz"></property>
        <property name="address" value="北极"></property>
</bean>

<bean id="s2" class="com.itbaizhan.domain.Student">
        <property name="id" value="2"></property>
        <property name="name" value="sxt"></property>
        <property name="address" value="上海"></property>
</bean>

(6)注入Properties对象:private Properties properties;//Properties类型

<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入Properties对象-->
        <property name="properties">
            <props>
                <prop key="配置1">值1</prop>
                <prop key="配置2">值2</prop>
            </props>
        </property>
</bean>