1、基于setter的依赖注入概念
基于setter的DI(依赖注入)通过在调用无参构造函数或无参的static工厂方法来实例化bean之后,再通过IOC容器调用bean的setter方法来实现的
ApplicationContext支持构造和基于setter方法的DI为它所管理的bean。它还支持基于setter的DI,一些依赖关系已经通过构造方法注入。
您可以以一种形式配置依赖项BeanDefinition,它与 PropertyEditor 实例一起使用,以将属性从一种格式转换为另一种格式。然而,
大多数Spring用户不直接与这些类(即,编程),而是用XML bean定义,注释组件(即与注释类@Component,@Controller等等),
或@Bean在基于Java的方法@Configuration类。然后将这些源内部转换为实例BeanDefinition并用于加载整个Spring IoC容器实例。
2、测试基于setter的依赖注入
一、普通类型的POJO对象注入
实例对象类:
package com.spring.mvc;
public class BeanSetter {
private String name;
private int age;
private String remark;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String toString() {
return "BeanSetter [name=" + name + ", age=" + age + ", remark="
+ remark + "]";
}
}
XML文件配置:
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<bean name="beanSetter" class="com.spring.mvc.BeanSetter">
<property name="name" value="小明"></property>
<property name="age" value="21"></property>
<property name="remark" value="小明今年21岁了"></property>
</bean>
</beans>
测试函数:
package com.spring.mvc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainDome {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
BeanSetter beSetter = (BeanSetter)ctx.getBean("beanSetter");
System.out.println(beSetter.toString());
}
}
测试结果:
二、组合型对象注入 使用ref(关联)
POJO对象:
package com.spring.mvc;
public class BeanSetter {
private String name;
private int age;
private String remark;
private Student student;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String toString() {
return "BeanSetter [name=" + name + ", age=" + age + ", remark="
+ remark + ", student=" + student.toString() + "]";
}
}
package com.spring.mvc;
public class Student {
private String grade;
private String classNumber;
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getClassNumber() {
return classNumber;
}
public void setClassNumber(String classNumber) {
this.classNumber = classNumber;
}
public String toString() {
return "Student [grade=" + grade + ", classNumber=" + classNumber + "]";
}
}
XML文件配置:
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<bean id="beanSetter" class="com.spring.mvc.BeanSetter">
<property name="name" value="小明"></property>
<property name="age" value="21"></property>
<property name="remark" value="小明今年21岁了"></property>
<property name="student" ref="student"></property>
</bean>
<bean id="student" class="com.spring.mvc.Student">
<property name="grade" value="初中"></property>
<property name="classNumber" value="一年级"></property>
</bean>
</beans>
测试函数:
package com.spring.mvc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainDome {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
BeanSetter beSetter = (BeanSetter)ctx.getBean("beanSetter");
System.out.println(beSetter.toString());
}
}
测试结果:
4、依赖注入过程(翻译api)
容器执行如下的bean依赖解析:
- ApplicationContext是通过描述所有bean的配置元数据创建和初始化的。可以通过XML,Java代码或注释指定配置元数据。
- 对于每个bean,如果使用它,而不是正常的构造函数,其依赖关系以静态工厂方法的属性,构造函数参数或参数的形式表示。当bean实际创建时,这些依赖关系被提供给bean 。
- 每个属性或构造函数参数是要设置的值的实际定义,或对容器中另一个bean的引用。
- 作为值的每个属性或构造函数参数都将从其指定的格式转换为该属性或构造函数参数的实际类型。默认情况下,Spring能够转换成字符串格式提供给所有的内置类型,比如数值int,long,String,boolean等。
创建容器时,Spring容器会验证每个bean的配置。但是,在bean 实际创建之前,bean属性本身不会被设置。单个范围并设置为预实例化(默认)的Bean将在创建容器时创建。否则,只有在请求时才创建该bean。创建bean可能会导致创建bean的图形,因为bean的依赖关系及其依赖关系(等等)被创建和分配。请注意,这些依赖关系中的解决方案不匹配可能会出现较晚,即首次创建受影响的bean。
一般可以信任Spring做正确的事情。它可以在容器加载时检测配置问题,例如对不存在的bean和循环依赖项的引用。当bean实际创建时,Spring会尽可能晚地设置属性并解析依赖关系。这意味着如果在创建该对象或其依赖关系时出现问题,则在请求对象时,可以正确加载的Spring容器可以生成异常。例如,bean由于缺少或无效的属性而抛出异常。某些配置问题的这种潜在延迟的可见性是为什么ApplicationContext默认情况下实现单例bean。在实际需要创建这些bean之前,要花费一些前期时间和内存来创建创建这些bean的配置问题ApplicationContext。仍然可以覆盖此默认行为,以便单例bean将进行延迟初始化,而不是预先实例化。
如果没有循环依赖性存在,当一个或多个协作bean被注入到依赖bean中时,每个协作bean 在被注入依赖bean之前被完全配置。这意味着如果bean A对bean B有依赖关系,则Spring IoC容器在调用Bean A的setter方法之前完全配置bean B.换句话说,bean被实例化(如果不是一个预先实例化的单例),它设置依赖关系,并调用相关的生命周期方法(如配置的init方法 或InitializingBean回调方法)。