其他分享
首页 > 其他分享> > Spring 04: IOC控制反转 + DI依赖注入

Spring 04: IOC控制反转 + DI依赖注入

作者:互联网

Spring中的IOC

基于注解的IOC

注解类型

a. 创建对象的注解

b. 依赖注入的注解

简单类型的注入

引用类型的注入

注意

考虑到演示代码的复用性,减少代码冗余,并保证演示的清晰性,放在一起演示的代码:共用实体类 + 共用applicationContext.xml + 共用一个测试类。
不在一起演示的,另建一个新包并重新创建以上内容。
对实体类或配置文件的修改顺序,遵循博文的演示顺序。

--------------------------------------------------------------------------------------------------------------------------------------------------

@Conponent注解

实体类

package com.example.s01;

import org.springframework.stereotype.Component;

@Component
public class Student {
    private String name;
    private int age;

    public Student() {
        System.out.println("Student无参构造方法被执行,实例对象被创建....");
    }

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

applicationContext.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 添加包扫描 -->
    <context:component-scan base-package="com.example.s01"/>
</beans>

测试1

package com.example.test;

import com.example.s01.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestComponent {
    //测试Component注解
    @Test
    public void testComponent(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("s01/applicationContext.xml");
        //获取容器中的bean对象
        Student student = (Student) ac.getBean("student");
        System.out.println(student);
    }
}

测试输出1

Student无参构造方法被执行,实例对象被创建....
Student{name='null', age=0}

Process finished with exit code 0

注意

实体类

@Component("stu")
public class Student {
	//...
}

测试2

public class TestComponent {
    //测试Component注解
    @Test
    public void testComponent(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("s01/applicationContext.xml");
        //获取容器中的bean对象
        Student student = (Student) ac.getBean("stu");
        System.out.println(student);
    }
}

测试输出2

@value注解

实体类

@Component("stu")
public class Student {
    @Value("荷包蛋")
    private String name;
    @Value("20")
    private int age;
    //....
}

测试3

测试输出3

Student无参构造方法被执行,实例对象被创建....
Student{name='荷包蛋', age=20}

Process finished with exit code 0

--------------------------------------------------------------------------------------------------------------------------------------------------

@Autowired注解

同源类型注入3种情况之一:完全相同的类型的注入

实体类

package com.example.s02;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class School {
    @Value("nefu")
    private String name;
    @Value("哈尔滨")
    private String address;

    public School() {
        System.out.println("School无参构造方法执行,实例对象被创建....");
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
package com.example.s02;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Student {
    //.....
    
    @Autowired
    private School school;
    
    //.....
}

applicationContext.xml

    <!-- 添加包扫描 -->
    <context:component-scan base-package="com.example.s02"/>

测试4

package com.example.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAutowired {
    //测试同源注入:完全相同的类型
    @Test
    public void testAutowired(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("s02/applicationContext.xml");
        //从容器中获取Student实例对象
        System.out.println("学生对象: " + ac.getBean("student"));
    }
}

测试输出4

School无参构造方法执行,实例对象被创建....
Student无参构造方法被执行,实例对象被创建....
学生对象: Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}}

Process finished with exit code 0

对应的名称注入

实体类

@Component("theSchool")
public class School {
	//.....
}
@Component
public class Student {
    //.....
    
    @Autowired
    @Qualifier("theSchool")
    private School school;
    
    //.....
}

测试5和测试输出5

注意

实体类

@Component
public class Student {
    //.....
    
    @Qualifier("theSchool")
    private School school;
    
    //.....
}

测试6

测试输出6

School无参构造方法执行,实例对象被创建....
Student无参构造方法被执行,实例对象被创建....
学生对象: Student{name='荷包蛋', age=20, school=null}

Process finished with exit code 0

--------------------------------------------------------------------------------------------------------------------------------------------------

@Autowired注解

同源类型注入3种情况之二:父子类型的注入

实体类

package com.example.s03;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SubSchool extends School{
    @Value("nefu附小")
    private String name;
    @Value("香坊区")
    private String address;

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

    public SubSchool() {
        System.out.println("SubSchool无参构造方法被执行,实例对象被创建....");
    }
}
package com.example.s03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Student {
    //......

    @Autowired
    private School school;
    //......
}
package com.example.s03;

import org.springframework.stereotype.Component;

@Component
public class SubSchool extends School{
    //......
}

applicationContext.xml

    <!-- 添加包扫描 -->
    <context:component-scan base-package="com.example.s03"/>

测试7

package com.example.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAutowiredExtend {
    //测试同源类型注入:父子类型
    @Test
    public void testAutowiredExtend(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("s03/applicationContext.xml");
        //从容器中获取Student实例
        System.out.printf("Student实例: " + ac.getBean("student"));
    }
}

测试输出7

School无参构造方法执行,实例对象被创建....
Student无参构造方法被执行,实例对象被创建....
School无参构造方法执行,实例对象被创建....
SubSchool无参构造方法被执行,实例对象被创建....
Student实例: Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}}
Process finished with exit code 0

注意

实体类

@Component("schoolFu")
public class School {
	//......
}
@Component("school")
public class SubSchool extends School{
	//......
}

测试8

测试输出8

School无参构造方法执行,实例对象被创建....
Student无参构造方法被执行,实例对象被创建....
School无参构造方法执行,实例对象被创建....
SubSchool无参构造方法被执行,实例对象被创建....
Student实例: Student{name='荷包蛋', age=20, school=SubSchool{name='nefu附小', address='香坊区'}}
Process finished with exit code 0

对应的名称注入

实体类

@Component
public class Student {
    @Autowired
    @Qualifier("schoolFu")
    private School school;
    //......
}

测试9

测试输出9

School无参构造方法执行,实例对象被创建....
Student无参构造方法被执行,实例对象被创建....
School无参构造方法执行,实例对象被创建....
SubSchool无参构造方法被执行,实例对象被创建....
Student实例: Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}}
Process finished with exit code 0

标签:School,实体类,04,DI,对象,Spring,Component,Student,public
来源: https://www.cnblogs.com/nefu-wangxun/p/16609243.html