SpringIoC依賴注入的過程(三)
上文說到doCreateBean的applyMergedBeanDefinitionPostProcessors方法找到了所有的聲明了Autowired标注和Resource标注的字段和方法,以及聲明了PostConstruct和PreDestroy标注的方法。到此為止,bean的依賴關系都已經解析到BeanDefinition中,接下來就是利用這些依賴關系進行注入。繼續看doCreateBean方法的剩餘部分
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);
}
});
}
這部分代碼是什麼意思呢?可以看到有一個變量名字叫做allowCircularReferences,可以猜出這裡就是處理循環引用的。比如Service1引用了Service2,而Service2也引用了Service1。如果現在正在建立Service1,發現它依賴了Service2,在向Service1注入Service2的過程中肯定要先去建立Service2。這時候發現又要建立Service1,當然不能再建立一個Service1了,而是先将未初始化好的Service1引用先注入到Service2中。然後初始化Service2後再回過來注入到Service1中。關于循環引用的依賴注入過程也許後續會專門的詳細解讀,今天簡單帶過,先把主體的流程說通。下面說SpringIoC的重頭戲, populateBean方法,依賴注入就發生在這裡。還是分段說吧,免得代碼太長
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
上面是要講的populateBean方法中的第一段代碼,它調用所有的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的方法。 InstantiationAwareBeanPostProcessor的實作類有下面這些
postProcessAfterInstantiation是在bean被執行個體化以後留出的擴充方法,但實際上并沒有用到,上面那些類都是直接傳回了true,依賴注入不是發生在這裡。我們繼續往下看
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
這裡是一處依賴注入發生的地方,如果目前的bean是AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE的主動注入模式,則會觸發相應的注入方法。先看一下autowireByName
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
很好了解,先找到需要注入的依賴的bean的名字,然後遞歸調用getBean。getBean執行完後就會傳回依賴的bean的執行個體,放入到PropertyValues中。再看看autowireByType是怎麼做的
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (!Object.class.equals(pd.getPropertyType())) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
根據類型自動注入的過程稍複雜一些,總體的過程是這樣的。通過resolveDependency方法最終調用DefaultListableBeanFactory中的doResolveDependency方法,然後得到需要注入的bean的執行個體,同樣先放到 PropertyValues中。不早了,先到這裡,剩下的後面繼續。