0
点赞
收藏
分享

微信扫一扫

[Spring]Spring的getBean路线-doCreateBean

前言

createBean进行了一些创建Bean实例前的工作:

  • 检查当前BeanDefinition的Class是否可以被解析.
  • 检查当前BeanDefinition的Lookup method是否存在,并且确认重载状态.
  • 激活Bean实例化前的后置处理器.

doCreateBean的总体流程

  • 根据当前Bean的构造策略进行实例化,此时的bean未进行依赖注入: createBeanInstance.
  • 解析Bean中被Spring注解标记的成员变量,如@AutoWired@ValueResource: applyMergedBeanDefinitionPostProcessors.
  • 判断是否要暴露早期引用的bean,为了解决循环依赖: addSingletonFactory.
  • 填充bean实例属性: populateBean.
  • 生命周期函数回调: initializeBean.
  • 判断在循环依赖的情况下Bean的引用是否一致: allowRawInjectionDespiteWrapping
  • 注册销毁方法: registerDisposableBeanIfNecessary

1. 根据当前Bean的构造策略进行实例化

1.1 BeanWrapper
public interface BeanWrapper extends ConfigurablePropertyAccessor {

    // 指定数组和集合自动增长的限制。默认不限制,即无限.
    void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);

    // 返回数组和集合自动增长的限制.
    int getAutoGrowCollectionLimit();

    // 返回当前BeanWrapper包装的Bean实例
    Object getWrappedInstance();

    // 返回当前BeanWrapper包装的Bean类型-Class
    Class<?> getWrappedClass();

    // 获取包装对象的PropertyDescriptors(由标准JavaBean自省确定)
    PropertyDescriptor[] getPropertyDescriptors();
    
    // 获取包装对象的PropertyDescriptor
    PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;

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

        // Instantiate the bean.
        // bean实例化包装类
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            // 从未完成创建的包装bean缓存中清理并获取相关的包装bean实例,单例,不可以重复
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 创建bean的方式有三种:
            // 1.Factory method 2.constructor 3. supplier
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 获取被包装的Bean,后续对bean的改动等于对wrapper进行改动,即对wrapper的改动也会改动bean
        Object bean = instanceWrapper.getWrappedInstance();
        // 获取实例化对象的类型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
@Controller
public class HelloController {
    @Autowired
    private HelloService helloService;

    public void hello(){
        System.out.println(helloService.hello()+",this is controller");
    }
}
  • AbstractAutowireCapableBeanFactory#createBeanInstance
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        // 获取Class对象,前面在createBean已经进行过解析了,这里会直接从mbd.getBeanClass()返回
        Class<?> beanClass = resolveBeanClass(mbd, beanName);
        // 检查是否可以破环private的保护进行反射创建实例
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }
        // 是否通过lambda的方式进行创建.在AbstractBeanDefinition中存储了此值.
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        // 通过工厂方法创建,factory-method
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        // 空参构造
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                // 如果已缓存的解析构造函数或者factoryMethod不为空
                // 那么可以利用构造函数解析
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            // 自动注入,调用构造函数自动注入
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                // 使用默认的构造函数构造
                return instantiateBean(beanName, mbd);
            }
        }

        // Candidate constructors for autowiring?
        // 根据参数解析确定构造函数
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        // 解析的构造器不为空 | 注入类型为AUTOWIRE_CONSTRUCTOR | 有参 | 传入的参数不为空
        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.
        // 如果没有推断出特殊的构造方法,使用这个默认的模式
        // 无参的默认构造方法,内部使用JDK的反射.
        return instantiateBean(beanName, mbd);
    }
  • AbstractAutowireCapableBeanFactory#instantiateBean
    protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(
                        (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
                        getAccessControlContext());
            }
            else {
                // 从这里开始调用反射,获取当前的初始化策略,进行初始化.
                // 默认使用 SimpleInstantiationStrategy.instantiate
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }
  • SimpleInstantiationStrategy#instantiate
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        // 如果Bean中的方法没有重写,则不需要CGLIB来重写
        // 通常这种情况会在 lookup method 和 replace method中
        if (!bd.hasMethodOverrides()) {
            Constructor<?> constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                // 获取对象的构造方法或者工厂方法
                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    final Class<?> clazz = bd.getBeanClass();
                    // 是否为接口
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            constructorToUse = AccessController.doPrivileged(
                                    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                        }
                        else {
                            // 获取默认的构造方法
                            constructorToUse = clazz.getDeclaredConstructor();
                        }
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Throwable ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            // newInstance
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            // Must generate CGLIB subclass.
            // 使用CGLIB进行动态代理
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

2. 解析Bean中被Spring注解标记的成员变量

        // 调用BeanDefinition属性合并后完成的BeanPostProcessor->MergedBeanDefinitionPostProcessor
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // @Value、@Autowired的注解解析入口
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
  • AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                // AutowiredAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor接口.
                // 该PostPorcessor会将被@Autowired、@Value标记的成员变量进行记录.
                // CommonAnnotationBeanPostProcessor也是MergedBeanDefinitionPostProcessor的一个实现.
                // 该类负责记录@Resource、@PostConstruct、@PreDestroy.
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }
2.1 Spring中的责任链模式
2.2 AutowiredAnnotationBeanPostProcessor
  • 构造函数
    /**
     * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
     * standard {@link Autowired @Autowired} annotation.
     * <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
     * if available.<br>
     * 为Spring的标准@Autowired注解创建一个新的AutowiredAnnotationBeanPostProcessor。<br>
     * 还支持JSR-330的@Inject注解。
     */
    @SuppressWarnings("unchecked")
    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
        try {
            this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                    ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - simply skip.
        }
    }
  • AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
2.3 InjectionMetadata
  • InjectionMetadata的核心成员变量
public class InjectionMetadata {

    private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
    /**
     * 目标class
     */
    private final Class<?> targetClass;
    /**
     * <p>当postProcessor处理bean时,会解析bean class的所有属性.</p>
     * <p>在解析时会判断属性上是否标记:@Value、@Autowired</p>
     * <p>如果有,那么对该属性值进行解析,将解析结果放入injectedElements中</p>
     * <p>可以说这是被注入元素的集合</p>
     */
    private final Collection<InjectedElement> injectedElements;


    /**
     * 和injectedElements一样,仅保存Spring默认处理的属性或者方法
     */
    @Nullable
    private volatile Set<InjectedElement> checkedElements;
  • InjectedElement

    /**
     * A single injected element.<br>
     * 单个注入元素。
     */
    public abstract static class InjectedElement {
        /**
         * 被注解标记的成员,Field还是Method.<br>
         * Member类是Field和Method的上层抽象.<br>
         */
        protected final Member member;
        /**
         * 是否为Field
         */
        protected final boolean isField;

        /**
         * 属性描述,JavaBean中的接口
         */
        @Nullable
        protected final PropertyDescriptor pd;

        @Nullable
        protected volatile Boolean skip;
    }
  • AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        // 获取类名---------例如:UserService<->userService
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        // 首先以最小的锁定快速检查并发映射。从容器中查找是否有给定类的autowired相关注解元信息.
        // 此处又见双重检测锁机制
        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
                        metadata.clear(pvs);
                    }
                    // 重新解析被@Autowired、@Value标记的成员
                    metadata = buildAutowiringMetadata(clazz);
                    // 重新将注解元数据放入缓存中
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }
  • AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

    /**
     * 解析当前Class被@Autowired标记的成员
     * @param clazz
     * @return
     */
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;
        // 递归遍历当前类及其所有基类,解析全部注解元信息
        do {
            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            // 收集被@Autowired、@Value标记的Field.
            // 利用反射机制获取给定类中所有的声明字段,获取字段上的注解信息
            // doWithLocalFields->获取当前类的所有Field,每个field执行lambda内的逻辑.
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // 此处逻辑较为复杂,通过debug发现如果为被标注的属性,会返回required:true.
                // 大致的意思是这个field是否被特定的注解标记?这里留一个疑问
                AnnotationAttributes ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    // 如果是static属性的成员,Spring不提供支持
                    if (Modifier.isStatic(field.getModifiers())) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static fields: " + field);
                        }
                        return;
                    }
                    // 判断required的状态
                    boolean required = determineRequiredStatus(ann);
                    // 将当前成员添加进currElements
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });

            // 上面是寻找被@Autowired和@Value标记的field,这里是寻找method
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                AnnotationAttributes 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;
                    }
                    // 如果方法不包含参数,打印警告信息
                    if (method.getParameterCount() == 0) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation should only be used on methods with parameters: " +
                                    method);
                        }
                    }
                    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);

        return new InjectionMetadata(clazz, elements);
    }

3. 检测是否需要提交暴露早期引用的Bean-addSingletonFactory

        // 向容器中缓存单例模式的Bean对象,以防止循环引用
        // 判断是否要暴露早期引用的bean
        // 1. 是否为单例.
        // 2. 是否允许循环引用
        // 3. 是否在创建中的bean
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 匿名内部类,防止循环引用,尽早只有对象的引用
            // 注意,此时的addSingletonFactory仅仅是注册了一个lambda代码块.
            // getEarlyBeanReference实现的是ObjectFactory的getObject方法.
            // 真正调用getObject的地方在doGetBean中的getSingleton中
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
  • DefaultSingletonBeanRegistry#addSingletonFactory
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                // 往三级缓存中添加
                this.singletonFactories.put(beanName, singletonFactory);
                // 从二级缓存中移除
                this.earlySingletonObjects.remove(beanName);
                // 记录注册单例的顺序
                this.registeredSingletons.add(beanName);
            }
        }
    }

4. 填充Bean实例的属性-populateBean

5. 生命周期函数回调-initializeBean

5.1 initializeBean入口-doCreateBean
        try {
            // 填充bean实例属性
            populateBean(beanName, mbd, instanceWrapper);
            // 初始化bean,过程:
            // 1. 判断是否实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware.
            // 如果有,将相关属性进行传递.
            // 2. 调用BeanPostProcessor的前置操作:例如->@PostConstruct
            // 3. 调用bean初始化的前置操作,即生命周期回调函数.
            // 实现InitializingBean#afterPropertiesSet、具有依赖注入的自定义方法
            // 4. 调用BeanPostProcessor的后置操作
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
5.2 AbstractAutowireCapableBeanFactory#initializeBean
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // 激活BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 激活BeanPostProcessor的postProcessBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 激活InitializingBean的afterPropertiesSet方法、initMethod
            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()) {
            // 激活BeanPostProcessor的postProcessAfterInitialization方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

6. 检测循环依赖,防止Bean出现不一样的引用.

        // 如果容器允许循环依赖,则进行相应处理
        if (earlySingletonExposure) {
            // 获取指定名称的已注册单例Bean对象.
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                // 如果经过initializeBean后获取到的Bean还是同一个(没有被增强)
                if (exposedObject == bean) {
                    // 确保byName获取到的Bean和正在实例化的Bean是同一个
                    exposedObject = earlySingletonReference;
                }
                // 如果上面的判断没通过,则表明引用的bean和注入的bean不一致
                // 此时有两个判断条件:
                // 1. 在循环引用的情况下是否要求注入原始bean实例,即使注入的bean最终被增强(AOP处理)也是如此.
                // 意思就是说,只认原始类型,如果在initializeBean中对bean进行了替换,Spring会认为是异常.
                // 2. 当前是否触发了循环依赖: dependentBeanMap记录着每个依赖于此Bean的Bean实例集合
                // 当发生循环依赖的时候不允许新创建实例对象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    // 获取依赖于当前bean的bean实例
                    for (String dependentBean : dependentBeans) {
                        // 移除掉只是用来进行类型检查的单例bean
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    // 因为bean创建后其依赖的bean一定是已经创建的
                    // actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有完全创建完
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

7. 注册销毁逻辑-registerDisposableBeanIfNecessary

doCreateBean流程图

举报

相关推荐

0 条评论