Spring源码分析(六)Bean生命周期源码解析4:创建Bean实例(实例化前、实例化、实例化后、自动注入、Aware、初始化前、初始化、初始化后...)

上一节,我们知道无论单例、原型、其他作用域,最终创建Bean实例都会调这个creatBean方法,而creatBean方法也不需要关心作用域到底是什么。

入口1:创建Bean总入口 - createBean

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

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

    if (logger.isTraceEnabled()) {...}
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    // 1.加载类
    // 马上要实例化Bean了,确保beanClass被加载了
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        //新new一个BeanDefinition,后续用的是这个
        mbdToUse = new RootBeanDefinition(mbd);
        //重新给beanClass属性赋值Class对象
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        //和@LookUp注解有关系,先不讲。
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {...}

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // 2. 实例化前
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {...}

    try {
        // 见入口2
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {...}
    catch (Throwable ex) {...}
}

1. 加载类

BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中,一开始就会调用:
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass

protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
        throws CannotLoadBeanClassException {

    try {
        //如果beanClass已经被加载了,直接返回class对象
        //	底层是判断this.beanClass instanceof Class
        //  之前说过一开始扫描生成的BeanDefinition这里其实是class的类名,String格式
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        if (System.getSecurityManager() != null) {...}
        else {
            //beanClass还没有被加载,则加载
            return doResolveBeanClass(mbd, typesToMatch);
        }
    }
    catch (PrivilegedActionException pae) {...}
    catch (ClassNotFoundException ex) {...}
    catch (LinkageError err) {...}
}

1.1 判断Class是否已经被加载

org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass

public boolean hasBeanClass() {
    //之前说过一开始扫描生成的BeanDefinition这里beanClass其实是class的类名,String格式
    //加载之后才会重新赋值为Class
    return (this.beanClass instanceof Class);
}

1.2 根据类名加载Class

如果beanClass属性的类型是Class,那么就直接返回
如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
        throws ClassNotFoundException {
	//获取类加载器
    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;

    if (!ObjectUtils.isEmpty(typesToMatch)) {...}

    String className = mbd.getBeanClassName();
    if (className != null) {
        //解析Spring表达式,有可能直接返回一个Class对象
        Object evaluated = evaluateBeanDefinitionString(className, mbd);
        if (!className.equals(evaluated)) {
            // A dynamically resolved expression, supported as of 4.2...
            if (evaluated instanceof Class) {
                return (Class<?>) evaluated;
            }
            else if (evaluated instanceof String) {
                className = (String) evaluated;
                freshResolve = true;
            }
            else {...}
        }
        if (freshResolve) {
            // When resolving against a temporary class loader, exit early in order
            // to avoid storing the resolved Class in the bean definition.
            if (dynamicLoader != null) {
                try {
                    //类加载器,加载Class
                    return dynamicLoader.loadClass(className);
                }
                catch (ClassNotFoundException ex) {...}
            }
            return ClassUtils.forName(className, dynamicLoader);
        }
    }

    // Resolve regularly, caching the result in the BeanDefinition...
    // 这里会重新给BeanDefinition的beanClass属性赋值Class对象
    return mbd.resolveBeanClass(beanClassLoader);
}
获取类加载器

org.springframework.beans.factory.support.AbstractBeanFactory#getBeanClassLoader

public ClassLoader getBeanClassLoader() {
    return this.beanClassLoader;
}

允许自定义指定BeanFactory的类加载器:
在这里插入图片描述

会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载。
在这里插入图片描述

org.springframework.util.ClassUtils#getDefaultClassLoader

public static ClassLoader getDefaultClassLoader() {
    ClassLoader cl = null;
    try {
        //优先获取线程中的类加载器
        cl = Thread.currentThread().getContextClassLoader();
    }
    catch (Throwable ex) {...}
    if (cl == null) {
        // No thread context class loader -> use class loader of this class.
        //线程中类加载器为null的情况下,获取加载ClassUtils类的类加载器
        //	ClassUtils.class是放在spring-core这个包里的
        //	如果spring-core这个包放到了jre/lib里,那getClassLoader就会为null
        //	因为ClassUtils是被Bootstrap类加载器加载的
        cl = ClassUtils.class.getClassLoader();
        if (cl == null) {
            // getClassLoader() returning null indicates the bootstrap ClassLoader
            try {
                //假如ClassUtils是被Bootstrap类加载器加载的,则获取系统类加载器
                cl = ClassLoader.getSystemClassLoader();
            }
            catch (Throwable ex) {...}
        }
    }
    return cl;
}

ClassUtils.getDefaultClassLoader():

  1. 优先返回当前线程中的ClassLoader
  2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
  3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器

优先返回当前线程中的ClassLoader的意义、应用场景:
首先我们可以通过API去设置当前线程的类加载器的

Thread.currentThread().setContextClassLoader();

而对于部署在tomcat里的应用程序,每个应用程序都会有一个对应的自定义的类加载器,这个类加载器是tomcat写的(目的是隔离每个应用程序),并且tomcat会把这个类加载器设置到线程的上下文里去,而Spring这里就可以通过Thread.currentThread().getContextClassLoader()获取到tomcat设置的自定义类加载器。

解析Spring表达式

org.springframework.beans.factory.support.AbstractBeanFactory#evaluateBeanDefinitionString

protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) {
    if (this.beanExpressionResolver == null) {
        return value;
    }

    Scope scope = null;
    if (beanDefinition != null) {
        String scopeName = beanDefinition.getScope();
        if (scopeName != null) {
            scope = getRegisteredScope(scopeName);
        }
    }
    //Spring表达式解析器解析,有可能直接返回一个Class对象
    return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}

Spring表达式用法:https://www.cnblogs.com/longyoudahai/p/15896070.html
简单来说就是spring xml中Bean的class属性,可以写一些表达式,动态设置class属性值。

beanClass属性重新赋值Class对象

org.springframework.beans.factory.support.AbstractBeanDefinition#resolveBeanClass

public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
    String className = getBeanClassName();
    if (className == null) {
        return null;
    }
    Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
	//这里重新覆盖设置了beanClass属性
    this.beanClass = resolvedClass;
    return resolvedClass;
}

2. 实例化前

应用场景

当前BeanDefinition对应的类成功加载后,就可以实例化对象了,但是…
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这个扩展点叫InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
在这里插入图片描述

比如:

@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("实例化前");
		}
		return null;
	}
}

如上代码会导致,在userService这个Bean实例化前,会进行打印。

值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:

@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("实例化前");
			//其实可以返回任意对象实例
			return new UserService();
		}
		return null;
	}
}

userService这个Bean,在实例化前会直接返回一个由我们所定义的UserService对象。如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。

源码分析

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        // isSynthetic表示合成,如果某些Bean是合成的,那么则不会经过BeanPostProcessor的处理
        // isSynthetic:返回此bean定义是否为“合成的”,即不是由应用程序本身定义的。
        // 2.1 判断Spring容器里是否注册了InstantiationAwareBeanPostProcessor
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //拿出beanName对应的Class
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                //执行实例化前
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    //执行初始化后!!!注意是初始化后,不是实例化后
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}
2.1 判断Spring容器里是否注册了InstantiationAwareBeanPostProcessor

org.springframework.beans.factory.support.AbstractBeanFactory#hasInstantiationAwareBeanPostProcessors

protected boolean hasInstantiationAwareBeanPostProcessors() {
    return !getBeanPostProcessorCache().instantiationAware.isEmpty();
}

BeanPostProcessorCache getBeanPostProcessorCache() {
    BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
    if (bpCache == null) {
        bpCache = new BeanPostProcessorCache();
        for (BeanPostProcessor bp : this.beanPostProcessors) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
                }
            }
            if (bp instanceof DestructionAwareBeanPostProcessor) {
                bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
            }
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
            }
        }
        this.beanPostProcessorCache = bpCache;
    }
    return bpCache;
}

Spring启动的时候,将所有BeanPostProcessor都存放到了beanPostProcessors,但是这个时候并不关心具体的类型
在这里插入图片描述

5.3之后新加的缓存BeanPostProcessorCache,对其做了分类:

static class BeanPostProcessorCache {

    final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();

    final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();

    final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();

    final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
}

这4个都是BeanPostProcessor的子类,主要目的就是对这些子类进行分类。

2.2 执行实例化前

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
            //有任意一个实现,返回了实例,则直接退出循环,后续不会再执行了
            return result;
        }
    }
    return null;
}

有任意一个实现,返回了实例,则直接退出循环,后续不会再执行了,为什么这么做呢?

  • 因为postProcessBeforeInstantiation方法,表达的含义就是实例化前会去执行,如果postProcessBeforeInstantiation实现里返回了一个对象,其实就已经算实例化了。

另外postProcessBeforeInstantiation方法里返回的对象可以是任意类型(为了灵活性),通过postProcessBeforeInstantiation生成的对象,只会经过初始化后,就返回了

2.3 执行初始化后
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        //有任意一个方法返回null会立即中断循环
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

默认返回自己,所以一般不会中断,返回null就认为需要中断后续的processor.postProcessAfterInitialization
在这里插入图片描述

入口2:真正开始创建实例阶段 - doCreateBean

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        //有可能在当前Bean创建之前,有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
        //针对FactoryBean的情况
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //3. 实例化,创建Bean实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();//对象
    Class<?> beanType = instanceWrapper.getWrappedClass();//对象的类型
    if (beanType != NullBean.class) {...}

    // Allow post-processors to modify the merged bean definition.
    //4. 后置处理合并后的BeanDefinition
    synchronized (mbd.postProcessingLock) {
        //同步锁+postProcessed,保证只会执行一次
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {...}
            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) {...}

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 入口3:属性填充阶段
        populateBean(beanName, mbd, instanceWrapper);
        // 入口4:初始化阶段
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {...}

    //循环依赖有关先不讲
    if (earlySingletonExposure) {...}

    // Register bean as disposable.
    try {
        //和bean销毁有关,看有没有定义过一些销毁Bean时需要执行的逻辑
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {...}

    return exposedObject;
}

3. 实例化

在这个步骤中就会根据BeanDefinition去创建一个对象了。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {...}

    //3.1 BeanDefinition中添加了Supplier,则调用Supplier来得到对象
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    //3.2 通过工厂方法实例化
    //	@Bean对应的BeanDefinition底层也是走这里进行实例化
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    // 一个原型BeanDefinition,会多次来创建Bean,那么就可以把该BeanDefinition所要使用的
    // 构造方法缓存起来,避免每次都进行构造
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
            	//检查是否缓存过
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    //resolved=true代表直接使用缓存的构造
    if (resolved) {
        //如果确定了当前BeanDefinition的构造方法,那么看是否需要进行对构造方法进行参数的
        if (autowireNecessary) {
        	//依赖注入(构造方法注入)
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            //如果不需要注入,则表示用的是默认无参构造方法,直接进行实例化
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪个构造方法
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

    // 如果ctors有值,则需要进行构造方法注入,或者autowireModle是AUTOWIRE_CONSTRUCTOR
    // 或者BeanDefinition中添加了构造方法的参数和值,或者调用getBean()方法时传入了args
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    // 看看有没有指明所要用的构造方法
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    // 如果没有@Autowired注解的构造方法
    // 当前BeanDefinition的autowiremode也不是AUTOWIRE_CONSTRUCTOR
    // 也没有指明所要用的构造方法
    // 则直接使用无参构造方法
    return instantiateBean(beanName, mbd);
}

3.1 Supplier创建对象

首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。
可以直接使用BeanDefinition对象来设置Supplier,比如:

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setInstanceSupplier(new Supplier<Object>() {
    @Override
    public Object get() {
        return new UserService();
    }
});
context.registerBeanDefinition("userService", beanDefinition);

3.2 工厂方法创建对象

如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod,比如:

方式一(静态工厂方法):

<bean id="userService" class="com.yth.service.UserService" factory-method="createUserService" />

对应的UserService类为:

public class UserService {

	public static UserService createUserService() {
		System.out.println("执行createUserService()");
		UserService userService = new UserService();
		return userService;
	}

	public void test() {
		System.out.println("test");
	}

}

方式二(实例工厂方法):

<bean id="commonService" class="com.yth.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />

对应的CommonService的类为:

public class CommonService {

	public UserService createUserService() {
		return new UserService();
	}
}

Spring发现当前BeanDefinition方法设置了工厂方法后,就会区分这两种方式,然后调用工厂方法得到对象。

值得注意的是,我们通过@Bean所定义的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常类似,@Bean所注解的方法就是factoryMethod,AppConfig对象就是factoryBean。如果@Bean所注解的方法是static的,那么对应的就是方式一。

3.3 推断构造方法

第一节已经讲过一遍大概原理了,后面会单独分析源码实现。推断完构造方法后,就会使用构造方法来进行实例化了。

额外的,在推断构造方法逻辑中除开会去选择构造方法以及查找入参对象以外,还会判断是否在对应的类中是否存在使用@Lookup注解了的方法。如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。

在实例化时,如果判断出来当前BeanDefinition中没有LookupOverride,那就直接用构造方法反射得到一个实例对象。如果存在LookupOverride对象,也就是类中存在@Lookup注解了的方法,那就会生成一个代理对象。

@Lookup注解就是方法注入,使用demo如下:

@Component
public class UserService {

	private OrderService orderService;

	public void test() {
		OrderService orderService = createOrderService();
		System.out.println(orderService);
	}

	@Lookup("orderService")
	public OrderService createOrderService() {
		return null;
	}

}

4. BeanDefinition的后置处理

应用场景

Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时合并好了的BeanDefinition进行加工,比如:

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		if ("userService".equals(beanName)) {
            //比如设置初始化方法
            beanDefinition.setInitMethodName("a");
            //比如,通过beanDefinition设置属性对应的值
			beanDefinition.getPropertyValues().add("orderService", new OrderService());
		}
	}
}

可以做很多事,当然只会影响Bean生命周期后续的流程,前面的流程已经执行过就不再影响了

在Spring源码中提供了一个默认实现,AutowiredAnnotationBeanPostProcessor(和@Autowired注解有关系)就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)。

在这里插入图片描述

(以后讲依赖注入的时候再讲。)

源码分析

synchronized (mbd.postProcessingLock) {
    //同步锁+postProcessed,保证只会执行一次
    if (!mbd.postProcessed) {
        try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {...}
        mbd.postProcessed = true;
    }
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}

入口3:属性填充阶段 - populateBean

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {...}

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // 5. 实例化后,属性设置之前
    //		isSynthetic:返回此bean定义是否为“合成的”,即不是由应用程序本身定义的。
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            //返回false,直接退出populateBean方法
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

    //6. 自动注入(Spring自带的依赖注入)
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        //MutablePropertyValues是具体的实现类
        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;
    }

    //7. 处理属性
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            //BeanDefinition上设置过的属性对应的值
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            //默认提供的实现里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法直接给对象中的属性赋值
            //		@Autowired、@Value、 @Inject 注解都是在这里实现的
            //		AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
            //CommonAnnotationBeanPostProcessor实现会处理@Resource注解
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                //postProcessPropertyValues过期了,不用再看了
                //	在工厂将给定的属性值应用到给定的bean之前,对它们进行后处理。
                //	允许检查是否满足了所有依赖项,例如基于bean属性设置器上的“Required"注解。
                pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    //返回null,直接退出populateBean方法
                    return;
                }
            }
            pvs = pvsToUse;
        }
    }
    if (needsDepCheck) {...}
	//如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值覆盖@Autowired
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

5. 实例化后

在处理完BeanDefinition后,Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),比如:

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

		if ("userService".equals(beanName)) {
			UserService userService = (UserService) bean;
			userService.test();
		}

		return true;
	}
}

上述代码就是对userService所实例化出来的对象进行处理。
这个扩展点,在Spring源码中基本没有怎么使用。

  • 此时传进来的Bean,还没有经过属性注入
  • 返回false,直接退出populateBean方法,可以不进行依赖注入

6. 自动注入(Spring自带的依赖注入)

这里的自动注入指的是Spring的自动注入,后续依赖注入章节单独讲。
DEMO:

xml方式:
在这里插入图片描述

@Bean方式

@ComponentScan("com.yth")
public class AppConfig {
    @Bean(autowire = Autowire.BY_TYPE)
    public OrderService orderService() {
        return new OrderService();
    }
}

//OrderService上什么注解都没有
public class OrderService {
    private User user;

    public void test() {
        System.out.println(user);
    }
	//一定要提供set方法!!
    public void setUser(User user) {
        this.user = user;
    }
}

@Component
public class User {
    public User() {
        System.out.println(1);
    }
}

运行结果:
在这里插入图片描述

一定要提供set方法(其实只要有set方法就行了,不用管成员变量,因为底层找的就是set方法而不是属性)

当找到set方法以后

  • 如果是BY_TYPE,就会根据set方法入参的类型去找Bean对象,找到以后传给set方法执行。
  • 如果是BY_NAME,就会根据setXxx方法的xxx去找Bean对象,找到以后传给set方法执行。

为什么有了这个功能还需要开发@Autowired注解方式注入呢?

  • 因为这个功能太灵活了,只要配置autowire模式,bean里面只要是set开头的方法都会去调
  • 而@Autowired注解方式可以更精确控制

7. 处理属性

这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过InstantiationAwareBeanPostProcessor.postProcessProperties()扩展点来实现的

  • AutowiredAnnotationBeanPostProcessor处理@Autowired、@Value、 @Inject 注解
  • CommonAnnotationBeanPostProcessor处理@Resource注解

我们也可以实现一个自己的自动注入功能,比如:

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            for (Field field : bean.getClass().getFields()) {
                if (field.isAnnotationPresent(MyInject.class)) {
                    field.setAccessible(true);
                    try {
                        field.set(bean, "123");
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return pvs;
    }
}

关于@Autowired、@Resource、@Value的底层源码,会在后续的依赖注入章节中讲解。

xml中的<context:annotation-config/>,相当于在容器里面注册了AutowiredAnnotationBeanPostProcessor…等

入口4:初始化阶段 - initializeBean

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {...}
    else {
        //8. 执行Aware
        invokeAwareMethods(beanName, bean);
    }

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

    try {
        //10. 初始化
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {...}
    if (mbd == null || !mbd.isSynthetic()) {
        //11. 初始化后
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

8. 执行Aware

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

完成了属性赋值之后,Spring会执行一些回调,包括:

  1. BeanNameAware:回传beanName给bean对象。
  2. BeanClassLoaderAware:回传classLoader给bean对象。
  3. BeanFactoryAware:回传beanFactory给对象。

9. 初始化前

应用场景

初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization(),比如

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            System.out.println("初始化前");
        }
        return bean;
    }
}

利用初始化前,可以对进行了属性填充后的Bean进行处理。

在Spring源码中:

  1. InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法
  2. ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:
    1. EnvironmentAware:回传环境变量
    2. EmbeddedValueResolverAware:回传占位符解析器
    3. ResourceLoaderAware:回传资源加载器
    4. ApplicationEventPublisherAware:回传事件发布器
    5. MessageSourceAware:回传国际化资源
    6. ApplicationStartupAware:回传应用其他监听对象,可忽略
    7. ApplicationContextAware:回传Spring容器ApplicationContext

源码分析

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            //一般不为null,如果传null就会中断后续执行直接返回
            return result;
        }
        result = current;
    }
    return result;
}

10. 初始化

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    //1.执行InitializingBean的afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {...}
        if (System.getSecurityManager() != null) {...}
        else {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    //2.执行BeanDefinition中指定的自定义的初始化方法
    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
  1. 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
  2. 执行BeanDefinition中指定的初始化方法(自定义的初始化方法)

11. 初始化后

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
        	//为null中断后续流程
            return result;
        }
        result = current;
    }
    return result;
}

这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization(),比如:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            System.out.println("初始化后");
        }

        return bean;
    }
}

可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

犬豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值