spring Autowired 代码注解自动注入源码分析
关键流程代码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])
//找出所有需要依懒注入的字段或者方法参数,保留进缓存
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//根据上面的查找,在缓存中查找出来,对bean进行填充
populateBean(beanName, mbd, instanceWrapper);
一阶段:
加载注解声明于代码:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredAnnotationBeanPostProcessor()
二阶段:
定位注解处,进行注入;
注意:org.springframework.util.ReflectionUtils.findMethod(Class<?>, String, Class<?>...)代码处进行该bean类的子类查找,找出所有需要注入的属性(包括子类的属性);
具体代码如下:
2016-06-14 15:49:54
"main" - Thread t@1
java.lang.Thread.State: RUNNABLE
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:327)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:318)
- locked <4fd2408f> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:217)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:840)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:495)
- locked <39990cf6> (a java.lang.Object)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
- locked <6f220804> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
- locked <233c779c> (a java.lang.Object)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.springapp.demo.Main2.main(Main2.java:19)
Locked ownable synchronizers:
- None
2016-06-14 13:14:16
"main" - Thread t@1
java.lang.Thread.State: RUNNABLE
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:318)
- locked <1259f252> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:217)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:840)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:495)
//在这里开始创建具体的bean
//具体代码中:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper)
//更具体的代码如下:
// if (bp instanceof InstantiationAwareBeanPostProcessor) {
// InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// continueWithPropertyPopulation = false;
// break;
// }
// }
//
//具体的填充为:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues)
//更具体的代码如下:
// Set our (possibly massaged) deep copy.
//try {
// bw.setPropertyValues(new MutablePropertyValues(deepCopy));
//org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(PropertyValues, boolean, boolean)
//}
//org.springframework.beans.BeanWrapperImpl.setPropertyValue(PropertyTokenHolder, PropertyValue) (这个方法挺长,不过还是容易理解
//final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :)
//这个方法用于判断到底使用普通的set方法注入,还是别外使用别的方式 ;
//这个方法用于查找之前需要注入的所有//InjectionMetadataorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(Class<?>)
// 关键注入代码是:org.springframework.beans.factory.annotation.InjectionMetadata.inject(Object, String, PropertyValues)
//可以看见以下两行代码,即是使用了反射注入@autowised bean:
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
//下面几行代码就是注入了:
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
- locked <5a89a850> (a java.lang.Object)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
- locked <3894aa0> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
- locked <2a825030> (a java.lang.Object)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.springapp.demo.Main.main(Main.java:20)
Locked ownable synchronizers:
- None