Spring依赖查找和依赖注入
演示简单的Bean工厂环境,使用Xml进行相关Bean的配置
- 定义两个简单的
POJO
,一个学生对象,一个体育生对象继承了学生对象并且扩展了其擅长的体育项目字段
@Data
public class Student {
private String name;
private Integer age;
}
@Data
@EqualsAndHashCode(callSuper = true)
public class SportsStudent extends Student{
private Sports goodAtSports;
public enum Sports {
BASKETBALL,FOOTBALL,SWIM
}
}
- 创建Xml上下文
META-INF/lookup-context.xml
1. 依赖查找
1.1 单一类型查找(通过名称/类型)
public class DependencyLookupDemo {
public static void main(String[] args) {
//1. 创建容器对象
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//2. 加载xml配置
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
//3. 加载BeanDefinition (加载学生Bean)
reader.loadBeanDefinitions("META-INF/lookup-context.xml");
//演示单一类型依赖查找
displaySimpleObjectLookup(beanFactory);
}
/**
* 演示简单类型的依赖查找
*/
private static void displaySimpleObjectLookup(DefaultListableBeanFactory beanFactory) {
//1. 根据名称查找,没指定类型需要强制类型转换
Student student = (Student) beanFactory.getBean("student");
//2. 根据类型查找, 若此时有多个Student对象,则会报错NoUniqueBeanDefinitionException
Student studentByType = beanFactory.getBean(Student.class);
//3. 根据类型+名称进行查找
Student studentByNameAndType = beanFactory.getBean("student", Student.class);
System.out.println(student);
System.out.println("studentByType == student is " + (studentByType == student));
System.out.println("student == studentByNameAndType is " + (student == studentByNameAndType));
}
}
// output
Student(name=lazylittle, age=18)
studentByType == student is false //student 和 sportsStudent比较 (primary)
student == studentByNameAndType is true // student 和 Student
1.2 复杂对象查找
private static void displayComplexObjectLookup(DefaultListableBeanFactory beanFactory) {
//1. 通过类型查询复杂类型
Map students = beanFactory.getBeansOfType(Student.class);
System.out.println("lookup complex object by type => " + students);
//2. 通过注解查询所有匹配的类型
Map studentsByAnnotation = beanFactory.getBeansWithAnnotation(Sport.class);
System.out.println("lookup complex object by annotation => " + studentsByAnnotation);
}
// output
// 1. 通过类型查询出来两个Student
lookup complex object by type => {student=Student(name=lazylittle, age=18), sportsStudent=SportsStudent(goodAtSports=SWIM)}
// 2. 通过Sport注解查找,只查找到了SportStudent
lookup complex object by annotation => {sportsStudent=SportsStudent(goodAtSports=SWIM)}
1.3 层次性查找/安全查找
- 修改加载的容器配置,添加上ParentBeanFactory
//1. 创建容器对象
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//2. 加载xml配置
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
//3. 加载BeanDefinition (加载学生Bean)
reader.loadBeanDefinitions("META-INF/lookup-context.xml");
//4. 设置父上下文,用来演示层次性查找
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("META-INF/parent-context.xml");
beanFactory.setParentBeanFactory(parent);
//演示层次性依赖查找
displayHierarchicalLookup(beanFactory,parent.getBeanFactory());
- 在父上下文中加载一个额外的Student来测试层次性的查找
1.3.1 层次性依赖查找
private static void displayHierarchicalLookup(ConfigurableListableBeanFactory child, ConfigurableListableBeanFactory parent) {
//1. 查找子容器中的所有Student对象
Map beansFromChild = child.getBeansOfType(Student.class);
//2. 查找父容器中的所有Student对象
Map beansFromParent = parent.getBeansOfType(Student.class);
//3. 层次性递归查找
Map beansFromHierarchical = BeanFactoryUtils.beansOfTypeIncludingAncestors(child, Student.class);
System.out.println("子容器中 student : " + beansFromChild);
System.out.println("父容器中 student : " + beansFromParent);
System.out.println("递归所有层级容器 student : " + beansFromHierarchical);
}
//output
子容器中 student : {student=Student(name=lazylittle, age=18), sportsStudent=SportsStudent(goodAtSports=SWIM)}
父容器中 student : {studentFromParent=Student(name=z3, age=50)}
//发现使用BeanFactoryUtils提供的递归查询工具类能查询到所有层级的Bean
递归所有层级容器 student : {student=Student(name=lazylittle, age=18), sportsStudent=SportsStudent(goodAtSports=SWIM), studentFromParent=Student(name=z3, age=50)}
BeanFactoryUtils递归依赖查找实现解析
层次性查找,若beanName有重复的,则子容器会覆盖父容器
public static Map beansOfTypeIncludingAncestors(ListableBeanFactory lbf, Class type)
throws BeansException {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
Map result = new LinkedHashMap<>(4);
result.putAll(lbf.getBeansOfType(type)); //1. 将当前上下文的所有对应类型bean加入到cache中
if (lbf instanceof HierarchicalBeanFactory) { //2. 若是层次性上下文,则去父容器中获取
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
Map parentResult = beansOfTypeIncludingAncestors( //3. 递归获取
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
parentResult.forEach((beanName, beanInstance) -> { //4. 合并,若没有beanName则进行设置,有则跳过
if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
result.put(beanName, beanInstance);
}
});
}
}
return result;
}
// output
子容器中 student : {student=Student(name=lazylittle, age=18), sportsStudent=SportsStudent(goodAtSports=SWIM)}
父容器中 student : {studentFromParent=Student(name=z3, age=50)}
递归所有层级容器 student : {student=Student(name=lazylittle, age=18), sportsStudent=SportsStudent(goodAtSports=SWIM), studentFromParent=Student(name=z3, age=50)}
1.3.2 安全性/延迟查找
通过ObjectFactory可以提供延迟查找功能,其中使用getObject()方法获取真实包含的Bean
Spring4.3提供了ObjectProvider类,添加了一系列的安全性延迟依赖查找,通过一些java8函数式技巧来进行安全查找,从而避免例如之前的NoUniqueBeanDefinitionException / NoSuchBeanDefinitionException等。。
在Xml添加一个Bean来演示ObjectFactory
演示相关代码如下
private static void displaySafeOrLazyLookup(DefaultListableBeanFactory beanFactory) {
ObjectProvider studentProvider = beanFactory.getBeanProvider(Student.class);
//1. 如果存在则消费
studentProvider.ifAvailable(System.out::println);
//2. Unique安全查找
System.out.println(studentProvider.getIfUnique());
//3. ObjectFactory延迟查找
beanFactory.getBeanProvider(ResolvableType.forClassWithGenerics(ObjectFactory.class, Student.class)).ifAvailable(System.out::println);
}
//output
SportsStudent(goodAtSports=SWIM)
SportsStudent(goodAtSports=SWIM)
- 可以通过
getBeanProvidedr()
来延迟安全查找 - 可以通过指定
ResolableType
来指定复杂泛型查找
2. 依赖注入
实验环境如下
- xml配置
- 启动环境
public class DependencyInjectionDemo {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
//1. 为了处理我们的@PostConstruct注解,添加一个Spring内置的CommonAnnotationBeanPostProcessor
applicationContext.addBeanFactoryPostProcessor(beanFactory ->
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor()));
applicationContext.setConfigLocation("META-INF/inject-context.xml");
//2. 启动上下文,会初始化所有的单实例Bean
applicationContext.refresh();
//3. 关闭上下文
applicationContext.close();
}
}
2.1 xml注入
2.1.1 setter注入
- 在Xml使用
完成setter注入 - 在
Student
类加入初始化回调@PostConstruct
展示注入的属性
@Data
public class Student {
private String name;
private Integer age;
private Address address;
@PostConstruct
public void showInjectedValue() {
System.out.println(this);
}
}
//output , 成功注入了引用bean和基本属性,并且spring能自动完成xml的string -> 需要的类型 (后序类型转化详细探讨)
Student(name=lazylittle, age=18, address=Address(addressName=HZ))
2.1.2 构造器注入
- 在
Student类中添加构造器
public Student(String name, Integer age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
- 在xml中使用
进行构造器注入
- 执行验证注入结果
//output,也是成功注入进来
Student(name=lazylittle, age=18, address=Address(addressName=HZ))
2.1.3 接口注入,通过Aware方式回调
这种方式一般都是在Spring Bean 刷新过程中 , 通过容器手动回调相关
setXXX方法
传入内建的xxxAware接口引用给自定义的Bean完成注入
-
Student
实现相关Aware
接口 , 以BeanNameAware
做示例,会通过setBeanName回调传入当前Student
的bean名称
@Data
public class Student implements BeanNameAware {
private String beanName;
@Override
public void setBeanName(String name) {
this.beanName = name;
}
}
- 检验结果
//output , beanName已经注入进来
Student(name=lazylittle, age=18, address=Address(addressName=HZ), beanName=student)
- 相关回调源码位置和实现 , 相关容器生命周期可以查看
AbstractAutowireCapableBeanFactory#invokeAwareMethods()
方法以及ApplicationContextAwareProcessor
//AbstractAutowireCapableBeanFactory
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName); //回调BeanNameAware
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);//回调BeanClassLoader
}
}
if (bean instanceof BeanFactoryAware) {//回调BeanFactory
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
//ApplicationContextAwareProcessor
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
2.2 annotation注入
启动上下文代码
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(DependencyInjectionWithComplexTypeDemo.class);
applicationContext.refresh();
applicationContext.close();
}
2.2.1 注解方式属性注入
相比于Xml的方式,Spring注解驱动可以通过使用@Autowired/@Resource/@Inject等注解完成属性注入,
而这些注入方式的 实现,是由
AutowiredAnnotationBeanPostProcessor/CommonAnnotationBeanPostProcessor
进行扫描对应注解并且使用反射注入。(后序源码分析的时候会重点分析)
- 属性注入一个
Address
对象,属性注入是注解驱动里面提供的。核心在AutowiredAnnotationBeanPostProcessor
中(源码解析中讲解)
public class Student implements BeanNameAware {
@Autowired // 可以替换成 @Resource @Inject , 甚至可以使用@Value注解注入外部化配置
private Address address;
}
- 校验结果
//output
Student{name='null', age=null, address=Address(addressName=HZ), beanName='student'}
2.2.2 注解方式setter注入
@Bean
public Address address() {
Address address = new Address();
address.setAddressName("HZ"); //使用setter方法注入addressName属性
return address;
}
2.2.3 注解方式构造器注入
- 可以不用
@Autowired
标注,但此时只能有一个带参构造 , (若有默认构造参数则会选择默认构造参数)
@Component
public class Student implements BeanNameAware {
private Address address;
public Student(Address address) {
this.address = address;
}
}
- 仅有一个@Autowired标注的构造方法,那么会受
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
方法回调,仅使用该构造器进行构造器注入
@Component
@NoArgsConstructor
public class Student implements BeanNameAware {
private Address address;
//会优先采用Autowired标记过的构造器
@Autowired(required = false)
public Student(Address address,String name) {
this.address = address;
this.name = name;
}
public Student(Address address) {
this.address = address;
}
- 若有多个
@Autowired
标记的构造器,那么只能同时为required=false
,否则会报BeanCreationException
异常 (至于为什么会出异常,后面源码解析会解释)
@Component
@NoArgsConstructor
public class Student implements BeanNameAware {
private Address address;
//会优先选择可用(容器中已经有的Bean)参数较多的构造器进行构造器注入
// 必须都标注为required=false才行。不然会报错
@Autowired(required = false)
public Student(String name,Address address) {
this.name = name;
this.address = address;
}
@Autowired(required = false)
public Student(Address address) {
this.address = address;
this.name = name;
}
2.2.4 注解方式接口注入 : 同Xml没有任何变化
2.2.5 复杂类型注入和分组注入
optional可选注入
@Configuration
public class DependencyInjectionWithComplexTypeDemo {
//注入可选Bean
@Autowired
private Optional helloOptional;
@PostConstruct
public void showResult() {
System.out.println(this.helloOptional);
}
延迟注入(ObjectFactory/ObjectProvider/@Lazy)
//ObjectFactory同ObjectProvider,但是ObjectFactory没有安全性查找
@Autowired
private ObjectProvider helloBeanProvider;
@PostConstruct
public void showResult() {
System.out.println(this.helloOptional);
System.out.println(this.helloBeanProvider);
System.out.println(this.helloBeanProvider.getIfAvailable(()->"fallback")); //安全性查找
System.out.println(this.helloBeanProvider.getObject()); //NoSuchBeanDefinitionException,No qualifying bean of type 'java.lang.String' available
}
@Lazy方式
@Autowired
@Lazy
private GenericHolder lazyBean; //注意这里不能使用String类型,@Lazy需要使用CGLIB生成代理对象(子类),final Class不能继承
@PostConstruct
public void showResult() {
//调用时会回调代理对象,此时会报错找不到Bean,因为上下文中压根没有GenericHolder Bean。但是不使用的话就不会报错
System.out.println(this.lazyBean);
}
集合类型加载(Collection,Array,Map)
@Autowired
private Collection hellos;
@Autowired
private String[] helloArray;
//会注入 k: beanName v: bean value
@Autowired
private Map helloMap;
@PostConstruct
public void showResult() {
System.out.println("Collection Way => "+this.hellos);
System.out.println("Array Way => "+ Arrays.toString(this.helloArray));
System.out.println("Map Way => "+this.helloMap);
}
//output
Collection Way => [hello, hello1]
Array Way => [hello, hello1]
Map Way => {hello=hello, hello1=hello1}
java规范的Provider加载 , 其实底层通过适配方式适配到了spring的DefaultListtableBeanFactory#doResolveDependency()
@Autowired
private Provider> listProvider;
分组加载 : Qualifier
可以通过
@Qualifirer
注解进行分组注入,具体实现可以看QualifierAnnotationAutowireCandidateResolver#isQualifier
- 声明Bean的时候使用@Qualifier限定
- 注入的时候使用@Qualifier获取限定的分组Bean
public class DisplayQualifierAnnotationDemo implements InitializingBean {
@Autowired
private Collection helloCollection;
//加载所有分组名称为hello 或者名称为 hello的
@Autowired
@Qualifier("hello")
private Collection helloCollectionWithQualifier;
//加载所有分组名称为hello1 或者名称为 hello1的
@Autowired
@Qualifier("hello1")
private Collection hello1CollectionWithQualifier;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(this.helloCollection);
System.out.println(this.helloCollectionWithQualifier);
System.out.println(this.hello1CollectionWithQualifier);
}
@Bean
public String hello() {
return "hello";
}
//申明该Bean属性hello分组
@Bean
@Qualifier("hello")
public String hello1() {
return "hello1";
}
}
//output
[hello, hello1]
[hello, hello1]
[hello1]
3. 依赖来源
依赖查找和依赖注入的元数据来源(BeanDefinition),基本一致,依赖注入多了一个
ResolvableDependencies
,如下,我们可以通过ConfigurableListableBeanFactory#registerResolvableDependency
注册这种类型的Bean提供给依赖注入时使用,但是此时依赖查找是获取不到的
public class DisplayResolvableDependency
{
@Autowired
private String hello;
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(DisplayResolvableDependency.class);
applicationContext.getDefaultListableBeanFactory().registerResolvableDependency(String.class,"byResolvableDependency");
applicationContext.refresh();
//print hello prop
System.out.println(applicationContext.getBean(DisplayResolvableDependency.class).hello);
// lookup sting
System.out.println(applicationContext.getBean(String.class));
applicationContext.close();
}
}
//output
// 依赖注入正常
byResolvableDependency
//依赖查找找不到Bean
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available
4. 依赖注入相关源码解析
Xml和注解方式的实现大同小异,根据不同的方式可以分为以下几种
- xml setter方式注入
- Annotation属性注入
- 注解/xml构造器参数注入
- xml工厂方式注入/@Bean setter注入
xml setter方式注入
这种方式其实是在populateBean属性赋值阶段进行注入的。我们在xml中声明的
标签会被 XmlBeanDefinitionReader
读取然后映射为BeanDefinition中的PropertyValues
,然后通过依赖查找获取到属性的真实对象,最后通过反射注入到Bean中
- 相关xml环境配置
- 相关POJO
@Data
public class User {
private String name;
private Integer age;
}
- 引导启动类
public class DependencyInjectionSourceDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("META-INF/display-source-context.xml");
System.out.println(beanFactory.getBean(User.class));
}
}
- 分析,在BeanFactory环境下操作,容器不会自动初始化单实例Bean。所以在我们使用依赖查找
getBean(User.class)
时才开始Bean的创建,以及我们要源码分析的属性注入。我们忽略前面创建Bean,直接定位到属性赋值阶段 :AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
- debug
populateBean
,如图可以发现User
的BeanDefinition 在加载完Xml元信息之后已经有个两个PropertyValue
。
[图片上传失败...(image-330557-1607875540877)]
//AbstractAutowireCapableBeanFactory.class
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//1. 若当前BeanWrapper中没值,但是BeanDefinition中有值,则抛出异常。
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
//2. 这里如果有InstantiationAwareBeanPostProcessor,则会回调所有的
// InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(),若返回false则跳过属性赋值阶段
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//3. 如果是autowiring模式,则进入对应的注入方法中,这里我们没有使用autowiring所以都会跳过
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
//4. 这里也是InstantiationAwareBeanPostProcessor的生命周期回调,用来在赋值之前自定义当前的PropertyValues
// 这里也会跳过
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
// 5. 依赖检查,这列没有设置,跳过
// 主要是过滤 ignoredDependencyTypes , ignoredDependencyInterfaces中相关的类
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//6. 核心的应用属性方法
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
- 进入设置属性的核心方法
applyPropertyValues()
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//省略无关代码...
//1. 创建值解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 省略无关代码..
//2. 开始解析
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
//3. 类型转化相关,xml都是String类型,通过TypeConverter转化为Bean中对应的其他类型
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
//省略无关代码
//4. 使用反射进行属性设置,完成属性注入(其中包含PropertyAccessor相关的Api后续在数据绑定进行解析)
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
Annotation方式属性注入
这里其实分两块,但是逻辑一致
-
@Autowired
,@Inject
: 通过AutowiredAnnotationBeanPostProcessor
这个后置处理器来进行处理的 -
@Resource
: 通过CommonAnnotationBeanPostProcessor
进行处理的
核心步骤
扫描并构建相关注解元信息
回调时间点在创建Bean实例之后,暴露提前引用(ObjectFactory,用于解决循环依赖)之前,其实就是
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(RootBeanDefinition mbd, Class> beanType, String beanName)
回调,位置在AbstractAutowirCapableBeanFactory#applyMergedBeanDefinitionPostProcessors()
此时会回调AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()
,下面我们来跟源码:
- 进入
AutowiredAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
//1. 查询@Autowired相关元信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 2. 检查配置
metadata.checkConfigMembers(beanDefinition);
}
-
findAuttowiringMetadata()
方法加载了什么元信息?
//1. 查找Autowired元信息
private InjectionMetadata findAutowiringMetadata(String beanName, Class> clazz, @Nullable PropertyValues pvs) {
//判断缓存中是否有
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//核心方法,查找并构建成AutowiringMetadata
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
//2. 查找并构建AutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
//2.1 递归向父类依次获取元信息
do {
final List currElements = new ArrayList<>();
//2.2 获取当前类所有属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//2.3 获取@Autowired注解信息
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
//2.4 如果字段是static修饰的则直接return
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//2.5 判断是否是required @Autoiwred(required = true)
boolean required = determineRequiredStatus(ann);
//2.6 构造成AutowiredFieldElement并添加到候选元信息列表中
currElements.add(new AutowiredFieldElement(field, required));
}
});
//3. 处理所有方法,和属性类似
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
//... 省略相关日志
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
//设置方法元信息
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//4. 最后封装成InjectionMetadata
return InjectionMetadata.forElements(elements, clazz);
}
对要注入的属性进行依赖查找然后反射注入
第一步构造好了InjectionMetdata , 而后会到属性赋值生命周期
populateBean
之前会回调所有InstantiationAwareBeanPostProcessor#postProcessProperties()
方法,此时会进入到AutowiredAnnotationBeanPostProcessor
对应的回调中
// AbstractAutowireCapableBeanFactory#popultaeBea()
//1. 获取所有的InstantiationAwareBeanPostProcessor回调postProcessProperties()
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
//AutowiredAnnotationBeanPostProcessor
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//1. 之前在MergedBeanDefinitionPostProcess()回调中构建好了InjectionMetadata,此时会直接从缓存中返回
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//2. 执行注入
metadata.inject(bean, beanName, pvs);
}
return pvs;
}
//InjectionMetadata
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection checkedElements = this.checkedElements;
Collection elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
//1. 直接遍历从声明了@Autowired 的field和method 构建好的InjectedElement
for (InjectedElement element : elementsToIterate) {
//2. 依次执行注入方法
element.inject(target, beanName, pvs);
}
}
}
根据字段/方法选择对应的AutowiredElement实现
AutowiredFieldElement#inject()实现
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
//1. 封装成DependencyDescriptor , 这个对象非常重要,在依赖注入场景中是非常核心的对象
//其中包含了要注入的field , 或者方法相关参数元信息
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConvert,,er = beanFactory.getTypeConverter();
try {
//2. 这个方法是注入的核心方法,用来根据我们的依赖描述对象DependencyDescriptor获取到候选的Bean对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
//3. 注册依赖关系以及缓存设置相关
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
}
if (value != null) {
//4. 反射设置属性
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
AutowiredMethodElement#inject()
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//1. 缓存相关处理
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
//2. 封装DependencyDescriptor,执行依赖查找
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
//省略注入依赖和相关缓存处理...
if (arguments != null) {
try {
//3. 反射注入
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
核心查找依赖过程AutowireCapableBeanFaactory#resolvableDependency()
- 方法声明如下
/**
* descriptor : 要解析的依赖描述,比如A中注入B , 那么这里为B的详细描述,里面有 field / method / consturct等信息
* requestingBeanName : B的名称
* autowiredBeanNames : resolvableDependency中查找到所有依赖的Bean集合
* typeConverter: 类型转化相关
**/
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
-
DependencyDescriptor
核心依赖描述对象,保存了要注入的依赖属性的相关元信息
//比如A中注入B
public class DependencyDescriptor extends InjectionPoint implements Serializable {
private final Class> declaringClass; //A的原生 Class对象,如果被CGLIB加强也不会是代理对象
@Nullable
private String methodName; // B如果是方法注入,则这里会是方法名称
@Nullable
private Class>[] parameterTypes; //方法参数类型
private int parameterIndex; //方法参数索引
@Nullable
private String fieldName; //B的属性名称
private final boolean required; //是否是必须的
private final boolean eager; //是否是饥饿的,true = 非懒加载
//嵌套层数,用来指定查找依赖类型的层数,比如declaringClass为 Optional> ,则为 ObjectProvider
private int nestingLevel = 1;
@Nullable
private Class> containingClass; //A的代理对象
@Nullable
private transient volatile ResolvableType resolvableType; //泛型信息
@Nullable
private transient volatile TypeDescriptor typeDescriptor; //类型描述
}
-
开始我们的
DefaultLisableBeanFactory#resolveDependency()
解析吧!!开门见山,一进来就快非常核心的几种不同类型的解析依赖类型(和循环依赖和懒加载相关)
- Optional : 非懒加载,不可解决构造器循环依赖,但可以注入不存在的Bean,不会出
NoSuchBeanDefinitionException
- ObjectFactory、ObjectProvider 、jsr 330 Provider : 懒加载,可解决构造器循环依赖
- @Lazy : 懒加载,会生成代理对象,可解决构造器循环依赖
- Optional : 非懒加载,不可解决构造器循环依赖,但可以注入不存在的Bean,不会出
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//1. 给DependencyDescriptor初始化名称探测器。用于探测属性/方法的参数名称。知道SpringMVC@RequestParam使用的小伙伴应该很熟悉这个组件
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//2. 如果依赖的类型是Optional,会返回Optional包装好的对象(非懒加载)
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
//3. ObjectFactory/ObjectProvider类型处理,返回DependencyObjectProvider对象,(懒加载)
// 后序要使用的时候可以通过getObject() / getIfAvaliable() 等获取依赖对象
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
//4. Jsr330 Provider类型处理 , 类似ObojectFactory , 通过get()方法获取依赖对象 (懒加载)
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
//5. @Lazy懒加载注解处理,会返回代理对象 (懒加载)
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//6. 处理一般POJO和集合数组等类型
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
- 这里我们优先来看
doResolveDependency
方法,这个比较复杂,会根据不同的依赖类型进行依赖查找。
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//1. 设置descriptor缓存(ThreadLocal)
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//1.1 如果descriptor 是快照类型,那么直接通过beanFactory.getBen()获取依赖Bean对象,因为快照类型的ShortcutDependencyDescriptor中缓存了解析好的beanName,具体在AutowiredFieldElement/AutowiredMethodElement中都解析成功后都会缓存好这个快照
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class> type = descriptor.getDependencyType();
//2. 处理@Value注解(外部化配置再详细探讨)
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//2.1 处理占位符
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
//2.2 类型转换如果需要的话,
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
//3. 处理负责类型解析和查找(Stream / Array / Collection /Map)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//4. 查找普通依赖
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
//4.1 没找到又是 required = true 抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//5. 当候选的注入Bean大于1个的时候,则按@Primary -> @Priority(javax.annotation.Priority) ->
// ResolvableDependency(通过ConfigurableListableBeanFactory#registerResolvableDependency) -> 根据名称(别名匹配)
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
//此时根据类型匹配有多个,但是无法评判出优先的bean则抛出NoUniqueBeanDefinitionException
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
//6. 依赖查找找到的候选Bean
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
//处理找不到的异常
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
上面步骤大概就是:
- 从快照中(ShortcutDependencyDescriptor)获取,如果有的话
- 处理
@Value
注解 -
resolveMultipleBeans()
解析复杂对象(Stream
,Array
,Collection
,Map
)查找,如果有的话 -
findAutowireCandidates()
解析简单pojo类型
protected Map findAutowireCandidates(
@Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) {
//1. 根据类型递归获取符合的beanName 数组
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
//2. 创建结果集容器
Map result = CollectionUtils.newLinkedHashMap(candidateNames.length);
//3. 尝试从ResolvableDependencies中获取候选Bean
for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
//4. 获取非自身Bean,以及通过泛型和Qualifier筛选
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
//4.1 添加到result结果集中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//5. 若没有则fallback匹配泛型不匹配的Bean
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
//6. 解析自己注入自己场景
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
-
determineAutowireCandidate()
若解析获取到的可匹配Bean有多个 (通过findAutowiredCandidates()
方法,处理泛型类型筛选,Qualifier筛选),则尝试获取最优的一个Bean,从 @Primary -> @Priority -> ResovlableDependency -> 具体名称)
protected String determineAutowireCandidate(Map candidates, DependencyDescriptor descriptor) {
Class> requiredType = descriptor.getDependencyType();
//1. 常用获取声明了primary的candidate
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
//1.1 若有直接返回
return primaryCandidate;
}
//2. 获取@Priority值大的
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
//3. 遍历候选Bean,先从resolvableDependencies中获取,若不存在则根据beanName来决定返回
for (Map.Entry entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
- 若没有找到,且为required=true则抛出NoSuchBeanDefinitionException,若不止一个最优Bean则抛出NoUniqueBeanDefinitionException
- Optional类型的解析相关处理
private Optional> createOptionalDependency(
DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {
//包装一个嵌套的依赖描述器,为什么要包装?这里其实将要检查的依赖类型层级+1了,比如Optional
//普通DependencyDescriptor只会查询Optional类型,而层级+1后则会检测Holder类型
DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
@Override
public boolean isRequired() {
return false;
}
@Override
public Object resolveCandidate(String beanName, Class> requiredType, BeanFactory beanFactory) {
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
super.resolveCandidate(beanName, requiredType, beanFactory));
}
};
//2. 查找最优依赖,发现这里不是懒加载,只是单纯使用Optional包裹了结果集
Object result = doResolveDependency(descriptorToUse, beanName, null, null);
//3. 如果返回为null,则返回空的Optional对象
return (result instanceof Optional ? (Optional>) result : Optional.ofNullable(result));
}
- ObjectFactory、ObjectProvider(SpringBoot大量使用其进行延迟构造)、Provider延迟加载类型
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
//直接返回一个DependencyObjectProvider对象
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
//该类为ObjectProvider的一个实现类
private class DependencyObjectProvider implements BeanObjectProvider
Provider : jsr330标准实现,方式类似ObjectProvider
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
//1. 也返回了一个DependencyObjectProvider实现,Jsr330Provider实现了Provider和ObjectProvider接口
//2. 调用其get()方法,即可适配到和ObjectProvider一样的方式
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
private class Jsr330Factory implements Serializable {
public Object createDependencyProvider(DependencyDescriptor descriptor, @Nullable String beanName) {
return new Jsr330Provider(descriptor, beanName);
}
private class Jsr330Provider extends DependencyObjectProvider implements Provider
@Lazy动态代理懒加载模式
else {
// DefaultListableBeanFactory#resolveDependency 处理@Lazy注解
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
return result;
}
//ContextAnnotationAutowireCandidateResolver#getLazyResolutionProxyIfNecessary
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
//1. 判断是否有@Lazy注解标注属性或者方法,有则构造代理对象并返回
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
//1.1 构建代理对象
TargetSource ts = new TargetSource() {
@Override
public Class> getTargetClass() {
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
//1.2 当正式使用代理对象的时候才会回调。
Set autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null);
//1.3 解析依赖Bean
Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
if (target == null) {
Class> type = getTargetClass();
if (Map.class == type) {
return Collections.emptyMap();
}
else if (List.class == type) {
return Collections.emptyList();
}
else if (Set.class == type || Collection.class == type) {
return Collections.emptySet();
}
throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
"Optional dependency not present for lazy injection point");
}
if (autowiredBeanNames != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (dlbf.containsBean(autowiredBeanName)) {
dlbf.registerDependentBean(autowiredBeanName, beanName);
}
}
}
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
//2. 使用 Spring 代理工厂构建代理对象返回
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
Class> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
return pf.getProxy(dlbf.getBeanClassLoader());
}
以上就是所有的属性注入流程。很是复杂,可以不需要关注太多细节知道大概的主要流程即可:
-
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
生命周期查找@Autowired元信息 - 属性赋值(populateBean)之前被
AutowiredAnnotationBeanPostProcessor#postProcessProperties()
拦截,并进行AutowiredFieldElement/AutowiredMethodElement注入- 通过
AutowireCapableBeanFactory#resolveDependency
解析依赖属性得到注入的Bean对象- 对Optional/ObjectProvider/@Lazy等类型进行特殊懒加载处理
- 根据类型查找所有bean并进行泛型类型,Qualifier等过滤
- 若AutowiredCandidate数量>1,则进行primary => priority => ResolvableDependencies => BeanName获取最优解并返回
- 使用反射进行注入
- 通过
xml构造参数注入/构造方法注入
这两种注入方式都是会在实例化Bean的时候,会采用返回的带参构造器进行实例化。
- 核心逻辑位置在
AbstractAutowirCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//省略无关当前分析的代码...
//1. 回调所有的SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors()方法尝试返回想要的构造器,这里我们会探讨AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors()
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//2. 若回调返回的构造器不为空,或者BeanDefinition也就是xml中配置了 都会返回true
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//3. 进行构造器自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
//4. 若没有返回构造器则使用默认构造器实例化Bean
return instantiateBean(beanName, mbd);
}
- 解析
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors()
是如何返回候选的构造器
public Constructor>[] determineCandidateConstructors(Class> beanClass, final String beanName)
throws BeanCreationException {
//省略lookup相关。。。
//1. 优先从候选构造器缓存中获取
// Quick check on the concurrent map first, with minimal locking.
Constructor>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor>[] rawCandidates;
try {
//2. 缓存中为null则或许该BeanClass的所有构造器
rawCandidates = beanClass.getDeclaredConstructors();
}
List> candidates = new ArrayList<>(rawCandidates.length);
Constructor> requiredConstructor = null;
Constructor> defaultConstructor = null;
//3. kotlin相关实现,忽略即可
Constructor> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
//4. 迭代所有构造器进行过滤
for (Constructor> candidate : rawCandidates) {
//4.1 非合成构造器
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
//4.2 获取构造器上@Autowired相关元信息
MergedAnnotation> ann = findAutowiredAnnotation(candidate);
//若没有尝试且当前BeanClass是CGLIB代理对象则尝试获取被代理对象的元信息
if (ann == null) {
Class> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 有Autowired元信息
if (ann != null) {
//4.3 则判断若已经有@Autowired(require = true)的候选构造器了,则说明一个Bean中不能有多个@Autowired(true)标注的构造器,否则 BeanCreationException
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//4.4 获取require属性值
boolean required = determineRequiredStatus(ann);
if (required) {
//4.5 此时若有多个Autowired标注的构造器参数会报错(这里多个指的同时包含require=true/false)两种,若有多个@Autowired(require=false)是可以的正常返回的。
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
//设置默认构造参数
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
//5 若没有@Autowired(required=true)的构造器
if (requiredConstructor == null) {
//默认构造器不为null则添加到候选构造器中作为fallback
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
//5.1 将候选Bean装成数组返回(此时可能是只有一个@Autowired(required=true)或者一个或多个@Autowired(required=false)的构造器)
candidateConstructors = candidates.toArray(new Constructor>[0]);
}
//6. 若没有@Autowired标记的构造器且当前BeanClass只有一个非默认构造器的时候,直接返回
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor>[] {rawCandidates[0]};
}
//kotlin相关跳过
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor>[] {primaryConstructor};
}
else {
//7. 返回空构造器
candidateConstructors = new Constructor>[0];
}
//8. 将解析好的构造器设置到缓存中
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
核心逻辑和流程如下
- 判断缓存中是否存在当前BeanClass对应的解析好的构造器,有则返回
- 获取
BeanClass
所有的构造器,遍历符合要求的构造器,要求如下:- 只有一个
@Autowired(required=true)
的构造器和其他没有标记@Autowired
的构造器 - 有一个或者多个
@Autowired(required=false)
的构造器 - 只有一个带参构造器
- 只有一个
- 设置到缓存中并返回
- 进入
autowireConstructor()
进行构造器注入
//进行构造器自动注入
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
autowireConstructor()
核心方法解析,这个方法比较长,建议参考步骤总结挑着看
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor>[] chosenCtors, @Nullable Object[] explicitArgs) {
//1. 初始化BeanWrapper,设置类型转换相关
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//2. 缓存处理
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
//3. 构造器选择,若没有则获取BeanClass的所有构造器
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
Constructor>[] candidates = chosenCtors;
if (candidates == null) {
Class> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
//3.1 若只有一个构造器,且BeanDefinition没有配置构造器参数
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor> uniqueCandidate = candidates[0];
//3.2 若是默认构造器则直接设置缓存相关参数然后反射实例化并设置到BeanWrapper中
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
//3.3 若传入的构造器不为null则autowiring为true
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//3.4 若有构造器参数,则进行评判并返回构造参数最小值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//会进行依赖查找并解析构造参数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//3.5 对所有候选的构造器进行排序 public优先,然后参数多的优先
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE; //默认最小类型差异权重
Set> ambiguousConstructors = null; //参数相同位置不同的构造器Construct A(String a,Integer b) Construct B(Integer a, String b) 这两就是这种类型
Deque causes = null; //异常记录
//4. 迭代所有候选的构造器
for (Constructor> candidate : candidates) {
int parameterCount = candidate.getParameterCount(); //构造器参数个数
//4.1 若已经有候选的构造器了,则和当前需要迭代的构造器和参数个数进行比较,若已经候选的构造器参数多则可以直接返回了(因为是根据参数个数从多到少排序,所以那个候选的构造器为参数最多的构造器可直接返回)
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
//4.2 参数小于 个数限制直接跳过
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//4.3 进行构造属性进行依赖查找
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//5. 根据参数类型返回一个差异值
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
//5.1 若小于最小权重,则设置构造器属性
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
//若有参数相同,则都设置到ambiguousConstructors中
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
//有类型相同但位置不同的构造器且模式为非宽松检查模式会抛出异常
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
//最后使用候选构造器反射实例化对象并设置到BeanWrapper中即可
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
总结:
- 若已经解析过构造器参数,则会命中缓存,直接返回匹配的构造器
- 开始解析所有的候选的构造器
- 若只有一个默认构造器,则直接返回
- 若有构造器参数
(
,则解析构造器参数属性值,通过) BeanDefinitionValueResolver#resolveValueIfNecessary()
依赖查找构造器参数值 - 对候选的构造器进行排序(public 优先,参数数量优先)
- 迭代有序的构造器,找出参数个数
ParameterCount
>=
,且属性参数最多的构造器进行返回,这里有一个有意思的宽松检查机制,即针对参数个数 construct A(String a,Integer b)
和construct B(Integer a,String b)
这两个属性一致,位置不一致的,会被添加到Set
中,最后会根据Bean中构造器定义的顺序返回> ambiguousConstructors - 最后使用
InstantiationStrategy#instantiate()
方法进行反射注入
工厂方法实例化/@Bean实例化
和构造器注入方式都一样,就是将构造器改成了特定的工厂方法,详细可以参考
ConstructorResolver#instantiateUsingFactoryMethod()
方法