您的位置:首页 > 编程语言 > Java开发

spring 源码学习笔记(二)—— spring ioc 之依赖注入

2017-11-20 21:04 681 查看
欢迎访问我的个人博客休息的风

上一篇spring系列博客spring 源码学习笔记(一)—— spring ioc 之加载XML转换为BeanDefinition讲到spring如何将xml文件转换为内存的数据结构。本篇博客将继续上篇博客,继续分析如何利用beanDefinition创建bean对象,并且对对象进行依赖注入。

下图是整个创建bean并依赖注入的过程:(看不清可右击在新页签进行查看)



AbstractAutowireCapableBeanFactory为创建bean的核心类,很多操作都在这个类里实现;我们主要关注这个类的方法。createBean方法作为入口


protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
//这里的RootBeanDefinition就是之前从xml解析转换的内存数据结构
RootBeanDefinition mbdToUse = mbd;

//省略代码。。。。
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//这里会去调用BeanPostProcessorsBeforeInstantiation,
// 包括用于aop的AnnotationAwareAspectJAutoProxyCreator处理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//省略代码。。。。
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}


doCreateBean方法用于真正创建bean实例

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean包装类实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

//省略代码。。。

// Initialize the bean instance.
Object exposedObject = bean;
try {
//填充RootBeanDefinition的字段
populateBean(beanName, mbd, instanceWrapper);
//初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}


createBeanInstance方法创建的是bean的包装类实例BeanWrapperImpl。后面populateBean方法中,需要通过这个包装类进行依赖注入。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
//省略代码。。。。

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这里进行实例的后置处理,aop的AnnotationAwareAspectJAutoProxyCreator也在这里调用
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.
c2af
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;
}

//省略代码。。。。

//设置属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}


这里只是在beanDefinition层面上注入,调用initializeBean方法开始对象的初始化。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//实现Aware接口的设置
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//初始化前置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
//调用afterPropertiesSet后再调用类的构造函数
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//初始化后置处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}


到此,基本的依赖注入过程已成形,这里总结一下整个过程:调用实例化前置处理器->创建包装类,对beanDefinition进行属性填充->根据beanDefinition进行初始化->初始化前后分别调用各自的处理器,初始时调用afterPropertiesSet->返回单例注册到DefaultListableBeanFactory中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息