IOC/DI

发布时间 2023-04-10 13:12:36作者: lwx_R

IOC:控制反转,对象控制权由代码交给容器
DI:依赖注入,为控制反转提供实现方法。

1.DI方式

  • 构造器注入
  • 属性注入
  • 接口注入

1.1 构造器注入

在被注入的类声明一个构造方法(有参或无参),Spring通过反射调用构造方法,进而创建对象

1.2 属性注入

在被注入类声明set方法,通过参数注入

  • Student
public class Student {
    public Student(String msg) {
        this.msg = msg;
    }

    public Student(){

    }
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Student{" +
                "msg='" + msg + '\'' +
                '}';
    }
}
  • spring.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
                            https://www.springframework.org/schema/beans/spring-beans.xsd"
       xmlns:p="http://www.springframework.org/schema/p">

    <bean id="student" class="entity.Student">
<!--        1.构造器注入属性值
                通过构造器-->
        <constructor-arg name="msg" value="MSG"></constructor-arg>
<!--        2.属性注入
                通过set方法-->
        <property name="msg">
            <value>LWX</value>
        </property>
<!--        3.接口注入-->
    </bean>
</beans>
  • Test类
@Test
public void fun(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/spring.xml");
    Student student = applicationContext.getBean("student",Student.class);
    System.out.println(student.getMsg());
}

2.DI方式

2.1 注入集合

  • Mix实体
public class Mix {
    private List<String> list;
    private Map<String, String> map;
    private String[] arr;

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public String[] getArr() {
        return arr;
    }

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    @Override
    public String toString() {
        return "Mix{" +
                "list=" + list +
                ", map=" + map +
                ", arr=" + Arrays.toString(arr) +
                '}';
    }
}
  • spring.xml
<bean id="mix" class="entity.Mix">
  <property name="list">
      <list>
          <value>list1</value>
          <value>list2</value>
      </list>
  </property>

  <property name="map">
      <map>
          <entry key="key1" value="map1"></entry>
          <entry key="key2" value="map2"></entry>
      </map>
  </property>

  <property name="arr">
      <array>
          <value>arr1</value>
          <value>arr2</value>
      </array>
  </property>
</bean>

2.2 注入对象属性

利用ref元素

  • Clazz实体
public class Clazz {
    private List<Student> students;

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Clazz{" +
                "students=" + students +
                '}';
    }
}
  • spring.xml
 <bean id="clazz" class="entity.Clazz">
<!--        第一种-->
    <property name="students">
        <list>
            <ref bean="student"></ref>
        </list>
    </property>
<!--        第二种-->
    <property name="students" ref="student"></property>
</bean>

2.3 P命名空间注入

上述实体

<!--    p命名空间-->
    <bean id="clazz" class="entity.Clazz" p:students-ref="student"></bean>

2.3 SpEL注入

Spring Expression Language 表达式语言 为Bean属性进行动态赋值 通过bean的id引用bean 调用对象方法或属性

  • Person实体
public class Person {
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Person{" +
                "msg='" + msg + '\'' +
                '}';
    }
}
  • spring.xml
<!--    SpEL注入-->
    <bean id="person" class="entity.Person">
        <property name="msg" value="#{student.msg}"></property>
    </bean>

3.Bean

3.1 配置

3.2 作用域

容器创建bean实例时可以指定其作用域,默认singleton

3.3 生命周期

bean创建,初始化,销毁的过程。

  • 初始化之前:init-method属性或实现initializingBean接口
  • 销毁之前:destroy-method属性或实现DisposableBean接口
  • Bean01实体
public class Bean01 implements DisposableBean {

    public Bean01(){

    }

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void init(){
        System.out.println("INIT");
    }

    public void close(){
        System.out.println("CLOSE");
    }

    @Override
    public void destroy() throws Exception {

    }
}
  • spring.xml
<bean id="bean01" class="entity.Bean01" init-method="init" destroy-method="close">
    <property name="value" value="MyValue"></property>
</bean>

4.注解

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

   <context:component-scan base-package="entity"></context:component-scan>
</beans>
  • stu实体类
@Component("stu")
public class Stu {
    public Stu(String msg) {
        this.msg = msg;
    }

    public Stu(){

    }
    @Value("MSG")
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Student{" +
                "msg='" + msg + '\'' +
                '}';
    }
}
  • Sch实体类
@Component("sch")
@Scope(scopeName = "singleton")
public class Sch {
    @Autowired
    @Qualifier("stu")//注入该实例
    private Stu stu;

    @PostConstruct
    public void init(){
        System.out.println("INIT");
    }

    @PreDestroy
    public void close(){
        System.out.println("CLOSE");
    }
}