Spring深入浅出(五),依赖注入,构造函数/设值/注入内部Bean

依赖注入的概念

Spring 依赖注入(Dependency Injection,DI)和控制反转含义相同,它们是从两个角度描述的同一个概念。使用依赖注入可以更轻松的管理和测试应用程序。

当某个Java对象(调用者)需要调用另一个Java对象(被调用者)时,在传统模式下,调用者通常采用【new 被调用者】的代码方式来创建对象。如下图示:

在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建。这样控制权由应用代码转移到Spring容器,控制权发生反转,这就是Spring的控制反转。

从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。依赖注入的方式有两种:构造方法注入、属性setter方法注入;本文顺带介绍注入内部Bean。

一、Spring 基于构造方法的依赖注入

1. 主业务类

package com.clzhang.spring.demo;

public class TextEditor {
       private SpellChecker spellChecker;
       public TextEditor(SpellChecker spellChecker) {
          System.out.println("Inside TextEditor constructor." );
          this.spellChecker = spellChecker;
       }
       public void spellCheck() {
          spellChecker.checkSpelling();
       }
}

2. 业务逻辑实现类

package com.clzhang.spring.demo;

public class SpellChecker {
    public SpellChecker() {
        System.out.println("Inside SpellChecker constructor.");
    }

    public void checkSpelling() {
        System.out.println("Inside checkSpelling.");
    }
}

3. 主程序

package com.clzhang.spring.demo;

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

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        TextEditor te = (TextEditor) context.getBean("textEditor");
        te.spellCheck();
    }
}

4. 配置文件

<?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-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.clzhang.spring.demo.TextEditor">
      <constructor-arg ref="spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.clzhang.spring.demo.SpellChecker">
   </bean>
 </beans>

5. 输出

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

二、Spring 基于属性setter方法的依赖注入

1. 主业务类

package com.clzhang.spring.demo;

public class TextEditor {
    private SpellChecker spellChecker;

    // a setter method to inject the dependency.
    public void setSpellChecker(SpellChecker spellChecker) {
        System.out.println("Inside setSpellChecker.");
        this.spellChecker = spellChecker;
    }

    // a getter method to return spellChecker
    public SpellChecker getSpellChecker() {
        return spellChecker;
    }

    public void spellCheck() {
        spellChecker.checkSpelling();
    }
}

2. 业务逻辑实现类

package com.clzhang.spring.demo;

public class SpellChecker {
    public SpellChecker() {
        System.out.println("Inside SpellChecker constructor.");
    }

    public void checkSpelling() {
        System.out.println("Inside checkSpelling.");
    }
}

3. 主程序

package com.clzhang.spring.demo;

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

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        TextEditor te = (TextEditor) context.getBean("textEditor");
        te.spellCheck();
    }
}

4. 配置文件

<?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-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.clzhang.spring.demo.TextEditor">
      <property name="spellChecker" ref="spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.clzhang.spring.demo.SpellChecker">
   </bean>
 </beans>

5. 输出

Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.

 三、注入内部Bean

Java 中在类内部定义的类称为内部类,同理在 Bean 中定义的 Bean 称为内部 Bean。注入内部 Bean 使用 <property> 和 <constructor-arg> 中的 <bean> 标签。

文件配置大概参考二、Spring 基于属性setter方法的依赖注入,只是Bean.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-3.0.xsd">

   <!-- Definition for textEditor bean using inner bean -->
   <bean id="textEditor" class="com.clzhang.spring.demo.TextEditor">
      <property name="spellChecker">
         <bean class="com.clzhang.spring.demo.SpellChecker"/>
       </property>
   </bean>
 </beans>

内部 Bean 的定义不需要指定 id 和 name 。如果指定了,容器也不会将其作为区分 Bean 的标识符,反而会无视内部 Bean 的 scope 属性。所以内部 Bean 总是匿名的,而且总是随着外部 Bean 创建。

注意:在实际开发中很少注入内部 Bean,因为开发者无法将内部的 Bean 注入外部 Bean 以外的其它 Bean。

输出如下:

Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.

本文参考:

https://www.w3cschool.cn/wkspring/vneb1mm9.html

https://blog.csdn.net/dfBeautifulLive/article/details/103239976

原文地址:https://www.cnblogs.com/nayitian/p/15001515.html