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.
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