目录
一、spring容器(DI)依赖注入的几种实现方式。
(1)手动注入。
(2)自动注入。
(3)图解如下。
二、spring容器实现(DI)依赖注入-setter注入方式。
(1)setter注入方式的基本介绍。
(2)setter注入方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
1、定义需交给spring容器管理的bean类。
2、spring配置文件中配置bean。(XML)
重点标签<property name="?" ref="?">。
3、使用spring容器来获取Bean的实例。
三、spring容器实现(DI)依赖注入-构造器注入方式。
(1)构造器注入方式的基本介绍。
(2)构造器注入方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
1、定义需交给spring容器管理的bean类。
2、spring配置文件中配置bean。(XML)
重点标签<constructor-arg ref="">。
3、使用spring容器来获取Bean的实例。
四、spring容器实现(DI)依赖注入-自动装配方式。
(1)自动装配方式的基本介绍。
(2)自动装配方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
1、spring配置文件中配置bean与开启自动装配。(XML)
<1>属性autowire="byName"。
<2>属性autowire="byType"。
- 本篇博客围绕spring容器对(bean实例化)与(bean与bean之间依赖关系)的管理。
一、spring容器(DI)依赖注入的几种实现方式。
(1)手动注入。
- 通过手动提供“需要依赖注入的属性与setter方法”完成注入操作。
- 通过手动提供“有参构造方法且方法参数为需要依赖注入属性”完成注入操作。
(2)自动注入。
- 内部运行时,还是依靠提供setter方法实现。
- 需要使用属性"autowire"来实现。
(3)图解如下。
- 具体是spring容器实现DI(依赖注入)的几种方式如下展示。
二、spring容器实现(DI)依赖注入-setter注入方式。
(1)setter注入方式的基本介绍。
- 在spring框架中,DI(依赖注入)是一种实现IoC(控制反转)的重要机制。
- 它允许对象在创建时不必关心依赖对象的创建和获取,而是将这些依赖关系由外部容器(spring容器)来管理。spring提供了多种依赖注入的方式,其中setter注入是一种常见的方法。下面就来演示具体的实现步骤。
(2)setter注入方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
- 提供实体类"A"与"B"。分别位于demo包下。
- 测试类MainApp。其中代码内容是关于使用spring容器加载配置文件并获取对应Bean。内部使用setter方法实现依赖注入,获取成员变量的实例化bean。
- spring配置文件名:springBean.xml。
1、定义需交给spring容器管理的bean类。
- 类"A"代码。在A类中创建成员变量(类"B")。提供setter方法,通过依赖注入(DI)方式获取该属性的实例化bean。
- 提供成员方法save(),自身打印输出外,调用成员变量b(B类对象)的save()方法。
package com.fs.demo;public class A {//成员变量:B类属性(对象)B b;//提供setter方法public void setB(B b){this.b = b;}//A类save()方法public void save(){System.out.println("A save...");//通过依赖注入的方式获取B类的实例化bean//调用B类的save()方法b.save();} }
- 类"B"代码。类中提供成员方法save()。
package com.fs.demo;public class B {//B类save()方法public void save(){System.out.println("B save...");} }
2、spring配置文件中配置bean。(XML)
重点标签<property name="?" ref="?">。
- name属性值一定要与使用依赖注入的类(A类)的成员变量名相同。
<?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"><!--配置A类bean--><bean id="a" class="com.fs.demo.A"><!--name:对应A类中属性名 ref:依赖的类B(id)--><property name="b" ref="b"></property></bean><!--配置B类bean--><bean id="b" class="com.fs.demo.B"></bean></beans>
3、使用spring容器来获取Bean的实例。
- 该操作主要在测试类(MainApp)中实现!
- 通过spring容器ApplicationContext加载spring配置文件。再通过容器对象的getBean()方法获得相应的bean。最后调用方法完成操作。
package com.fs.test;import com.fs.demo.A; import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainApp {public static void main(String[] args) {//使用IoC容器(ApplicationContext)获取spring容器管理的bean对象//1.创建容器对象。实例化时参数指定对应的配置文件ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springBean.xml");//2.通过<bean>标签的唯一标识id获取对应在spring容器已经配置的bean对象(生产A类的bean)Object obj = context.getBean("a");//3.强制类型转换A a = (A) obj;a.save();} }
- 程序运行结果与简单解释。
三、spring容器实现(DI)依赖注入-构造器注入方式。
(1)构造器注入方式的基本介绍。
- 在spring框架中,构造器注入是一种依赖注入的方式。构造器注入方式通过构造器(有参构造方法)将依赖传递给Bean。
- 这种方式可以确保Bean在使用之前完全初始化,并且可以提供更好的编译时检查。
- 下面就来演示具体的实现步骤。
(2)构造器注入方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
- 提供实体类"C"与"D"。分别位于demo2包下。
- 测试类MainApp02。其中代码内容是关于使用spring容器加载配置文件并获取对应Bean。内部使用构造器实现依赖注入,获取成员变量的实例化bean。
- spring配置文件名:springBean.xml。
1、定义需交给spring容器管理的bean类。
- 类"C"代码。在C类中创建成员变量(类"D")。
- 不需要提供setter方法。只需提供对应的有参构造方法,且参数的类型为成员变量(类"D")。通过构造器实现依赖注入(DI)方式再获取该成员属性的实例化bean。
- 提供成员方法save(),自身打印输出外,调用成员变量d(D类对象)的save()方法。
package com.fs.demo2; //类C public class C {//只从代码上看,d好像空对象(null)//但最终因交给spring容器管理,通过DI完成bean的实例化D d;//构造器方式实现依赖注入(D类的成员变量d)public C(D d){this.d = d;}//类C的save()方法public void save(){System.out.println("C save...");//通过依赖注入的方式获取D类的实例化bean//调用D类的save()方法d.save();} }
- 类"D"代码。类中提供成员方法save()。
package com.fs.demo2;public class D {//类D的save()方法public void save(){System.out.println("D save...");} }
2、spring配置文件中配置bean。(XML)
重点标签<constructor-arg ref="?">。
把之前spring配置文件里面的<property>标签换成<constructor-arg>标签即可。其中属性"ref"的值为依赖注入的类对应标签<bean>所绑定的id即可。
<?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"><!--配置C类bean--><bean id="c" class="com.fs.demo2.C"><!--使用构造器(有参构造)给成员变量D类对象d实现依赖注入(实例化bean)--><constructor-arg ref="d"></constructor-arg></bean><!--配置D类bean--><bean id="d" class="com.fs.demo2.D"></bean></beans>
3、使用spring容器来获取Bean的实例。
- 该操作主要在测试类(MainApp2)中实现!
- 通过spring容器ApplicationContext加载spring配置文件。再通过容器对象的getBean()方法获得相应的bean。最后调用方法完成操作。
package com.fs.test;import com.fs.demo2.C; import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainApp02 {public static void main(String[] args) {//使用IoC容器(ApplicationContext)获取spring容器管理的bean对象//1.创建容器对象。实例化时参数指定对应的配置文件ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springBean.xml");//2.通过<bean>标签的唯一标识id获取对应在spring容器已经配置的bean对象(生产UserServiceImpl类的bean)Object obj = context.getBean("c");//3.强制类型转换C c = (C) obj;c.save();} }
- 程序运行结果与简单解释。
四、spring容器实现(DI)依赖注入-自动装配方式。
-
此模块的代码明天再完善。
(1)自动装配方式的基本介绍。
- 在spring框架中,自动装配(Autowiring)是一种自动解决Bean依赖关系的方式。
- 其实自动装配方式实现依赖注入的操作底层还是依赖setter方法。不显式的指定依赖关系其实就是将之前繁琐的<property>这步简化,通过属性"autowire"指定值(byName/byType)。值"byName"或"byType"具体的用法下面会介绍。
- spring容器可以在创建Bean时自动注入其他Bean的引用,而不需要显式地指定依赖关系。下面就来演示具体的实现步骤。
(2)自动装配方式的具体实现步骤。
0、demo(案例)准备工作(需知)。
- 提供实体类"C"与"D"。分别位于demo2包下。
- 测试类MainApp02。其中代码内容是关于使用spring容器加载配置文件并获取对应Bean。内部使用自动装配(底层依赖setter方法)实现依赖注入,获取成员变量的实例化bean。项目的测试不同情况:根据属性autowire值得不同进行不同的测试。
1、spring配置文件中配置bean与开启自动装配。(XML)
- 注意:可能通过文字的描述让人不太好理解。
<1>属性autowire="byName"。
- byName:就是寻找配置文件中所有<bean>内的属性id(先首字母转换成大写)是否与提供的setter方法后缀一致!如age——>setAge()、name——>setName()。否则无法通过setter方法自动装配完成依赖注入!
- 总之当autowire="byName"时<bean>的id与setter方法名息息相关的。下面博主测试了一部分情况。
- 如果<bean id="Age" .....> 对应提供的setter方法为:setAge()也是无法自动装配识别的。(也就是使用byName对应<bean>的id的首字母必须小写)
package com.fs.demo2; //类C public class C {D d;//自动装配底层还是依赖setter方法public void setD(D d) {this.d = d;}//类C的save()方法public void save(){System.out.println("C save...");//通过依赖注入的方式获取D类的实例化bean//调用D类的save()方法d.save();} }
<?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"><!--配置C类bean通过autowire属性指定依赖。不需要显式地使用ref指定依赖关系--><bean id="c" class="com.fs.demo2.C" autowire="byName"></bean><!--配置D类bean--><bean id="d" class="com.fs.demo2.D"></bean></beans>
- 测试结果:成功。(正常写法:首字母小写)
- 如果"id"字符串的首字母大写。报错!无法实现依赖注入。
<?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"><!--配置C类bean通过autowire属性指定依赖。不需要显式地使用ref指定依赖关系--><bean id="c" class="com.fs.demo2.C" autowire="byName"></bean><!--配置D类bean--><bean id="D" class="com.fs.demo2.D"></bean></beans>
- 测试结果:失败。
- "id"字符串中间有多个字符串可以大写或小写,只是对应setter方法名需要变更。
- 此时被依赖注入的bean绑定的id为"daaAge"。(首字母为小写,中间大小写,结尾为小写)
<?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"><!--配置C类bean通过autowire属性指定依赖。不需要显式地使用ref指定依赖关系--><bean id="c" class="com.fs.demo2.C" autowire="byName"></bean><!--配置D类bean--><bean id="daaAge" class="com.fs.demo2.D"></bean><!--配置D类bean--><!--<bean id="assAsE" class="com.fs.demo2.D"></bean>--><!--<bean id="c" class="com.fs.demo2.C" autowire="byName"></bean>--></beans>
- 只需要按要求将对应的setter方法名修改也是可以完成依赖注入的。
- "id"字符串末尾可以小写或大写,只是对应setter方法名需要变更。
<2>属性autowire="byType"。
- 这里就不需要关注setter方法的后缀名或者id的取值!
- 只需实现依赖注入的<bean>添加属性autowire="byType",然后可以在其他<bean>的属性"class"找到被依赖注入的类即可。
- 如"C"类需要使用依赖注入将"D"类的对象注入进来。那么在spring配置文件中"C"类对应的<bean>的属性autowire="byType"。"D"类对应的bean的"class"属性需要与"D"类的对象的类的引用一致。注意要求注入的Type只能是一个,如果有多个则发生报错。具体看下面。
- 正常写法。
package com.fs.demo2; //类C public class C {D d;//自动装配底层还是依赖setter方法public void setD(D d) {this.d = d;}//类C的save()方法public void save(){System.out.println("C save...");//通过依赖注入的方式获取D类的实例化bean//调用D类的save()方法d.save();} }
<?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"><!--配置C类bean通过autowire属性指定依赖。不需要显式地使用ref指定依赖关系--><bean id="c" class="com.fs.demo2.C" autowire="byType"></bean><!--配置D类bean--><bean id="d" class="com.fs.demo2.D"></bean><!--配置D类bean--><!--<bean id="assAsE" class="com.fs.demo2.D"></bean>--></beans>
- 提供对应Type的<bean>的class有多个时!会报错,因为程序不知道你要使用哪个!
- 提供对应Type的<bean>的class有多个时出现的异常信息。
- 就算再有一个类"A"去实现依赖注入类"D"对象。使用autowire="byType"也是不能让对应Type的<bean>的class为多个。无法识别到底使用哪个