千家信息网

Spring Bean怎么初始化

发表于:2025-11-11 作者:千家信息网编辑
千家信息网最后更新 2025年11月11日,这篇文章主要为大家展示了"Spring Bean怎么初始化",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Spring Bean怎么初始化"这篇文章吧。前言
千家信息网最后更新 2025年11月11日Spring Bean怎么初始化

这篇文章主要为大家展示了"Spring Bean怎么初始化",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Spring Bean怎么初始化"这篇文章吧。

前言

做Java都有很多年了,一直有一个疑惑: Spring 如何初始化bean,怎么调用反射实例化对象的,自己动手来解除这个疑惑。 过去我认为spring bean对象实例化一直都是由BeanPostProcessor接口实现类去做的,我就是不知道具体那个实现类。

三级缓存

为什么面试官特别喜欢问创建bean的三级缓存,主要是因为bean创建都是伴随着三级缓存之间的转换完成的,对象不同状态分别存在不同缓存中,下面我会在分析代码时,顺便支持对象如何在缓存中流转的。 先了解下spring 三级缓存。

    /** 一级缓存 用于存放完全可以使用单例bean,也就是初始化完成并且注入所有依赖 */        private final Map singletonObjects = new ConcurrentHashMap<>(256);        /** 二级缓存 过早暴露单例对象,此时bean刚刚完成初始化,未完成属性注入和执行 init 方法 */        private final Map earlySingletonObjects = new ConcurrentHashMap<>(16);        /** 三级缓存  装载创建bean的工厂对象 */        private final Map> singletonFactories = new HashMap<>(16)

三级缓存主要作用: 创建对象ObjectFactory首先放入三级换缓存中,当调用getObject 创建实例时,会将创建好对象加入二级缓存中,并且删除三级中缓存,当对象已经完成初始化方法和属性注入,再将缓存添加到一级缓存中,并且删除二级缓存。

doGetBean

从源头开始找,所有spring bean 初始化都是由AbstractBeanFactory.doGetBean方法实现的。下面我将源码减除臃肿部分,贴出来。

    protected  T doGetBean(                        String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)                        throws BeansException {        //name 前缀处理  beanFactory beanName 带有&开头                String beanName = transformedBeanName(name);                Object beanInstance;        //从三级缓存去取bean,三级中都没有则返回null,说明对象还没有创建                Object sharedInstance = getSingleton(beanName);                if (sharedInstance != null && args == null) { //如果缓存中bean 是FactoryBean实例,要通过接口获取到实际bean                        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);                }                else {              //判断bean对象标记是否正在创建中,如果正在创建中则不应该继续下去,出现依赖循环就会出现这个错误                        if (isPrototypeCurrentlyInCreation(beanName)) {                                throw new BeanCurrentlyInCreationException(beanName);                        }                        BeanFactory parentBeanFactory = getParentBeanFactory();            // 检查父容器是否存在,尝试从父容器中获取                        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {                                String nameToLookup = originalBeanName(name);                                if (parentBeanFactory instanceof AbstractBeanFactory) {                                        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(                                                        nameToLookup, requiredType, args, typeCheckOnly);                                }                                else if (args != null) {                                        return (T) parentBeanFactory.getBean(nameToLookup, args);                                }                                else if (requiredType != null) {                                        return parentBeanFactory.getBean(nameToLookup, requiredType);                                }                                else {                                        return (T) parentBeanFactory.getBean(nameToLookup);                                }                        }                        if (!typeCheckOnly) { //缓存中标记beanName 正在被创建                                markBeanAsCreated(beanName);                        }                        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")                                        .tag("beanName", name);                        try {                                if (requiredType != null) {                                        beanCreation.tag("beanType", requiredType::toString);                                }                                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);                                checkMergedBeanDefinition(mbd, beanName, args);                                // Guarantee initialization of beans that the current bean depends on.                                String[] dependsOn = mbd.getDependsOn();                                if (dependsOn != null) {  //bean 中@DependsOn 信息,用于标记bean之间初始化顺序,优先创建@DependsOn   中bean                                        for (String dep : dependsOn) {                                                if (isDependent(beanName, dep)) {                                                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                                                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");                                                }                                                registerDependentBean(dep, beanName);                                                try {                                                        getBean(dep);                                                }                                                catch (NoSuchBeanDefinitionException ex) {                                                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);                                                }                                        }                                }                             //创建单例对象                                if (mbd.isSingleton()) { //重点就在这里实例化对象  ,getSingleton 就是在这里将创建完成对象加入到一级缓存中                                        sharedInstance = getSingleton(beanName, () -> {                                                try {                                                        return createBean(beanName, mbd, args);                                                }                                                catch (BeansException ex)                                                         destroySingleton(beanName);                                                        throw ex;                                                }                                        });                    //如果生成bean 是FactoryBean ,再获取真正的对象                                        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);                                }                //作用域 = prototype,因为不会放入缓存中,每次获取都要重新创建                                else if (mbd.isPrototype()) {                                        // It's a prototype -> create a new instance.                                        Object prototypeInstance = null;                                        try {                                                beforePrototypeCreation(beanName);                                                prototypeInstance = createBean(beanName, mbd, args);                                        }                                        finally {                                                afterPrototypeCreation(beanName);                                        }                                        beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);                                }                                else { // session request 这些作用域,由作用域容器去管理这些对象                                        String scopeName = mbd.getScope();                                        if (!StringUtils.hasLength(scopeName)) {                                                throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");                                        }                                        Scope scope = this.scopes.get(scopeName);                                        if (scope == null) {                                                throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");                                        }                                        try {                                                Object scopedInstance = scope.get(beanName, () -> {                                                        beforePrototypeCreation(beanName);                                                        try {                                                                return createBean(beanName, mbd, args);                                                        }                                                        finally {                                                                afterPrototypeCreation(beanName);                                                        }                                                });                                                beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);                                        }                                        catch (IllegalStateException ex) {                                                throw new ScopeNotActiveException(beanName, scopeName, ex);                                        }                                }                        }                        catch (BeansException ex) {                                beanCreation.tag("exception", ex.getClass().toString());                                beanCreation.tag("message", String.valueOf(ex.getMessage()));                                cleanupAfterBeanCreationFailure(beanName);                                throw ex;                        }                        finally {                                beanCreation.end();                        }                }                //返回初始化成功的对象,一个对象初始化就这样完成的了                  return adaptBeanInstance(name, beanInstance, requiredType);          }

大概总结一下上面代码流程:

  • 先从三级缓存中获取,如果缓存中都没有。再去判断是否存在父容器,从父容器中获取。没有正式进入bean 初始化流程,先根据beanName 获取到RootBeanDefinition,bean类元信息、先处理dependsOn中bean,保证bean依赖的创建顺序,下面会说明org.springframework.context.annotation.@DependsOn这个注解。下一步按照不同scope 进行bean 对象初始化。初始化流程就是这样,我们将目光放在单例bean 如何实例化,集中关注AbstractAutowireCapableBeanFactory.createBean 获取注册一个单例对象

@DependsOn 注解意思是实例化某个对象依赖于某一个实例化,但是不需要持有这个实例对象。比如bean A上 需要依赖bean b才能实例化,但是bean b 不需要作为他的属性,常常用于不同实例实例化顺序标记。

看下getSingleton方法

    public Object getSingleton(String beanName, ObjectFactory singletonFactory) {                synchronized (this.singletonObjects) {                        Object singletonObject = this.singletonObjects.get(beanName);                        if (singletonObject == null) {                                if (this.singletonsCurrentlyInDestruction) { //标记bean 是否在销毁                                        throw new BeanCreationNotAllowedException(beanName,                                                        "Singleton bean creation not allowed while singletons of this factory are in destruction " +                                                        "(Do not request a bean from a BeanFactory in a destroy method implementation!)");                                }                                beforeSingletonCreation(beanName);                                boolean newSingleton = false;                                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);                                if (recordSuppressedExceptions) {                                        this.suppressedExceptions = new LinkedHashSet<>();                                }                                try {                                        singletonObject = singletonFactory.getObject();                                        newSingleton = true;                                }                                catch (IllegalStateException ex) {                                }                                catch (BeanCreationException ex) {                                        throw ex;                                }                                finally {                                        if (recordSuppressedExceptions) {                                                this.suppressedExceptions = null;                                        }                                        afterSingletonCreation(beanName);                                }                                if (newSingleton) {                                        addSingleton(beanName, singletonObject); //就是在这里删除二三级缓存,提交到一级缓存                                }                        }                        return singletonObject;                }        }        protected void addSingleton(String beanName, Object singletonObject) {                synchronized (this.singletonObjects) {                        this.singletonObjects.put(beanName, singletonObject);                        this.singletonFactories.remove(beanName);                        this.earlySingletonObjects.remove(beanName);                        this.registeredSingletons.add(beanName);                }        }

添加到一级缓存则说明bean已经完成实例化,可以正常使用了。下面看下如何进行实例化和属性注入的。

createBean

下面进入AbstractAutowireCapableBeanFactory.createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)                        throws BeanCreationException {                RootBeanDefinition mbdToUse = mbd;        //克隆一份mbd => mbdToUse                Class resolvedClass = resolveBeanClass(mbd, beanName);                if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {                        mbdToUse = new RootBeanDefinition(mbd);                        mbdToUse.setBeanClass(resolvedClass);                }                // Prepare method overrides.                try {                        mbdToUse.prepareMethodOverrides();                }                catch (BeanDefinitionValidationException ex) {                        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),                                        beanName, "Validation of method overrides failed", ex);                }                try {                        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.                //通过BeanPostProcessors 增强返回一个代理对象,这个生成AOP的代理对象,使用多个BeanPostProcessors来处理                        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);                        if (bean != null) {                                return bean;                        }                }                catch (Throwable ex) {                        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,                                        "BeanPostProcessor before instantiation of bean failed", ex);                }                try {            // bean 对象实例化就这里实现                        Object beanInstance = doCreateBean(beanName, mbdToUse, args);                        return beanInstance;                }                catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {                        throw ex;                }                catch (Throwable ex) {                        throw new BeanCreationException(                                        mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);                }        }

这里逻辑就比较简单了 ,克隆一份RootBeanDefinition用于初始化对象,resolveBeforeInstantiation 主要用于初始化代理对象情况,主要使用BeanPostProcessor子类InstantiationAwareBeanPostProcessor实现方法去实现对象初始化,并且在实例化成功后在调用后置方法进行对象依赖注入,这里可以看见此方法返回对象直接跳出方法栈,这里可以看出单例和代理对象还是有区别的。单例对象初始化就在doCreateBean 实现了

doCreateBean

下面就是AbstractAutowireCapableBeanFactory.doCreateBean非常接近对象如何实例化的了

   protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)                        throws BeanCreationException {                // Instantiate the bean.                BeanWrapper instanceWrapper = null;                if (mbd.isSingleton()) {                         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);                }                if (instanceWrapper == null) {                        instanceWrapper = createBeanInstance(beanName, mbd, args);  //这个就是实例化方法                }                Object bean = instanceWrapper.getWrappedInstance();                Class beanType = instanceWrapper.getWrappedClass();                if (beanType != NullBean.class) {                        mbd.resolvedTargetType = beanType;                }                // 使用BeanDefinitionPostProcessors 对合并bean进行实例化                 synchronized (mbd.postProcessingLock) {                        if (!mbd.postProcessed) {                                try {                                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                                }                                catch (Throwable ex) {                                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                                        "Post-processing of merged bean definition failed", ex);                                }                                mbd.postProcessed = true;                        }                }                // 这里就需要用到上面说的三级缓存知识了                // even when triggered by lifecycle interfaces like BeanFactoryAware.                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(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //将已经实例化的对象加入到第三级缓存 singletonFactories                 }                // Initialize the bean instance.                Object exposedObject = bean;                try {                        populateBean(beanName, mbd, instanceWrapper); //对属性进入注入,下面会具体分析的                        exposedObject = initializeBean(beanName, exposedObject, mbd); //执行初始化方法,或者注入Aware 接口bean                }                catch (Throwable ex) {                        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {                                throw (BeanCreationException) ex;                        }                        else {                                throw new BeanCreationException(                                                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);                        }                }                //下面代码省略               //主要就是对设置了DisposableBean 接口销毁钩子方法处理        }

这里代码主要分成三部分

  • 初始化实例,创建对象完成,并且添加到3级缓存。第3级缓存常常用于存储代理对象,因为有些类需要动态代理方法,需要生成代理对象,会委派给第三级缓存方法ObjectFactroy去实现的,普通对象如果不需要会直接返回。

  • 对实例化bean进行属性注入

  • 执行初始化方法,DisposableBean接口加入到disposableBeans容器中

instantiateBean

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()) {                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());                }                Supplier instanceSupplier = mbd.getInstanceSupplier();                if (instanceSupplier != null) {// 有实现Supplier 接口,由instanceSupplier.get() 方法创建实例                        return obtainFromSupplier(instanceSupplier, beanName);                }                //factoryName  使用工厂模式创建bean,调用工厂方法去创建,这个支持静态方法和factoryBean.invoke                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) {                                 if (mbd.resolvedConstructorOrFactoryMethod != null) {                                        resolved = true;                                        autowireNecessary = mbd.constructorArgumentsResolved;                                }                        }                }                if (resolved) {                        if (autowireNecessary) {                               //使用构造函数注入方式实例化                                return autowireConstructor(beanName, mbd, null, null);                        }                        else {                               //实例化对象                                return instantiateBean(beanName, mbd);                        }                }                // 获取构造函数参数                Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);                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.                return instantiateBean(beanName, mbd);        }

实例化方法instantiateBean最终会调用SimpleInstantiationStrategy.instantiate 进行实例化

instantiate

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {                // Don't override the class with CGLIB if no overrides.                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>) clazz::getDeclaredConstructor);                                                }                                                else {                                                        constructorToUse = clazz.getDeclaredConstructor(); //获取构造函数                                                }                                                bd.resolvedConstructorOrFactoryMethod = constructorToUse;                                        }                                        catch (Throwable ex) {                                                throw new BeanInstantiationException(clazz, "No default constructor found", ex);                                        }                                }                        }                        return BeanUtils.instantiateClass(constructorToUse); //调用构造函数进行实例化                }                else {                        // Must generate CGLIB subclass.                        return instantiateWithMethodInjection(bd, beanName, owner);                }        }

instantiateClass

       @Override        public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {                // Don't override the class with CGLIB if no overrides.                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>) clazz::getDeclaredConstructor);                                                }                                                else {                                                        constructorToUse = clazz.getDeclaredConstructor();                                                }                                                bd.resolvedConstructorOrFactoryMethod = constructorToUse;                                        }                                        catch (Throwable ex) {                                                throw new BeanInstantiationException(clazz, "No default constructor found", ex);                                        }                                }                        }                        return BeanUtils.instantiateClass(constructorToUse);  //调用构造器进行初始化                }                else {                        // Must generate CGLIB subclass.                        return instantiateWithMethodInjection(bd, beanName, owner);                }        }

这里要注意下先判断bean是否有方法重写的,没有则使用反射生成的构造器,有就使用gclib方式创建代理对象,具体实现方式就在org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate,有兴趣同学可以去学习下。 到此一个简单bean实例化完成了。

注入

下面进入IOC另一个特点,bean注入,先从AbstractAutowireCapableBeanFactory.populateBean方法开始

      protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {                // 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.              //通过InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation 如果返回true,目标实例内部的返回值会被populate,否则populate这个过程会被忽视            //翻译说如果返回true可以执行字段注入 真的6666啊                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {                        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {                                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {                                        return;                                }                        }                }                PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);                //获取注入方式分布有4种                int resolvedAutowireMode = mbd.getResolvedAutowireMode();                  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {                        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;                }                boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();            //依赖方式,模式都是没有类型检查,这种依赖方式一般都是xml 配置用得比较多,没有配置这里都是返回false                boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); /                PropertyDescriptor[] filteredPds = null;                if (hasInstAwareBpps) {                        if (pvs == null) {                                pvs = mbd.getPropertyValues();                        }                        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {                                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);  //获取注解标注需要注入方法或者是字段,并且进行注入                                if (pvsToUse == null) {                                        if (filteredPds == null) {                                                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);                                        }                                        pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);                                        if (pvsToUse == null) {                                                return;                                        }                                }                                pvs = pvsToUse;                        }                }                if (needsDepCheck) {                        if (filteredPds == null) {                                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);                        }                        checkDependencies(beanName, mbd, filteredPds, pvs);                }                if (pvs != null) {                        applyPropertyValues(beanName, mbd, bw, pvs);                }        }

小知识点: AutowireCapableBeanFactory.AUTOWIRE_NO 表明不会对当前Bean进行外部类的注入,常规使用@Autowire、@Resource 都是这类型 剩下三种都是通过xml 或者 AutowireCapableBeanFactory.autowire(Class beanClass, int autowireMode, boolean dependencyCheck) 进行设置autowireMode 。

根据上面代码可以知道主流程bean注入都是由InstantiationAwareBeanPostProcessor 进行处理的,简单说明接口方法

方法描述
postProcessBeforeInitialization方法是最 先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
postProcessAfterInitialization方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
postProcessPropertyValues对bean属性值赋值后调用,对属性值的修改。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改
postProcessPropertiesBean属性赋值就是调用这个方法的

InstantiationAwareBeanPostProcessor 接口实现类主要分3个

  • ConfigurationClassPostProcessor:看类名就知道处理@Configuration实例化,并没有属性注入逻辑,不详讲略过。

  • CommonAnnotationBeanPostProcessor:这个类就是实现bean注入,但是是实现JSR-250 注解、@Resource,@EJB、@WebServiceRef,@WebServiceContext,@PostConstrusct、@PreDestory这些注解实现。

  • AutowiredAnnotationBeanPostProcessor:实现 @Autowired、@Value注入,并且支持JSR-330's @Inject,主要分析这个类就可以知道bean 注入的。

AutowiredAnnotationBeanPostProcessor分析

    private final Set> autowiredAnnotationTypes = new LinkedHashSet<>(4);        @SuppressWarnings("unchecked")        public AutowiredAnnotationBeanPostProcessor() {                this.autowiredAnnotationTypes.add(Autowired.class);                this.autowiredAnnotationTypes.add(Value.class);                try {                        this.autowiredAnnotationTypes.add((Class)                                        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.                }        }

在初始化时就将支持注解加入集合中,再使用扫描器去扫描方法、构造器、字段,如果有这些注解就进行注入。

看下怎么判断是否需要注入的

    @Nullable        private MergedAnnotation findAutowiredAnnotation(AccessibleObject ao) {                MergedAnnotations annotations = MergedAnnotations.from(ao);                for (Class type : this.autowiredAnnotationTypes) {                        MergedAnnotation annotation = annotations.get(type);                        if (annotation.isPresent()) {                                return annotation;                        }                }                return null;        }

AccessibleObject 是Method、Field、Constructor 父类。

postProcessProperties 如何实现bean注入的

 public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {              //获取需要注入字段,方法                InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);                try {                        metadata.inject(bean, beanName, pvs); //注入                }                catch (BeanCreationException ex) {                        throw ex;                }                catch (Throwable ex) {                        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);                }                return pvs;        }       //下面就行获取InjectionMetadata         private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) {                // Fall back to class name as cache key, for backwards compatibility with custom callers.                String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());                // 快速从缓存中获取,如果没有加锁去解析,然后在结果放入缓存中                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.clear(pvs);                                        }                                        metadata = buildAutowiringMetadata(clazz);                                         this.injectionMetadataCache.put(cacheKey, metadata);                                 }                        }                }                return metadata;        }
  • InjectionMetadata 主要是集合bean需要被注入类型,因为已经解析过bean Class信息了,相当于解析结果装起来

看下如何去扫描方法、字段的

        private InjectionMetadata buildAutowiringMetadata(final Class clazz) {       //从给定注解中判断class 是否携带这个注解                if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {                         return InjectionMetadata.EMPTY;                }                List elements = new ArrayList<>();                Class targetClass = clazz;                do {                        final List currElements = new ArrayList<>();            //遍历所有Field,找出扫描的注解,特意标注不支持static 修饰field                         ReflectionUtils.doWithLocalFields(targetClass, field -> {                                MergedAnnotation ann = findAutowiredAnnotation(field);                                if (ann != null) {                                        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.add(new AutowiredFieldElement(field, required));                                }                        });                        ReflectionUtils.doWithLocalMethods(targetClass, method -> {                //获取方法上桥接方法,因为泛型类型擦除,要对桥接方法进行安全检查,防止在调用是出现异常                                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);                                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {                                        return;                                }                //获取注解                                MergedAnnotation 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); //这里写得很好,向上解析父类,直到是Object 为止                return InjectionMetadata.forElements(elements, clazz);        }

逻辑非常简单,就是根据给定注解去class获取指定的注解,从而获取到需要注入类型,但是几行简单的代码可以看出强大编码能力,学习了????。 现在需要注入对象已经获取到,看如何注入吧

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {                Collection checkedElements = this.checkedElements;                Collection elementsToIterate =                                (checkedElements != null ? checkedElements : this.injectedElements);                if (!elementsToIterate.isEmpty()) {                        for (InjectedElement element : elementsToIterate) {                                element.inject(target, beanName, pvs);                        }                }        }                @Override                protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {                        Field field = (Field) this.member;                        Object value;                        if (this.cached) {                                try {                                        value = resolvedCachedArgument(beanName, this.cachedFieldValue);                                }                                catch (NoSuchBeanDefinitionException ex) {                                        // Unexpected removal of target bean for cached argument -> re-resolve                                        value = resolveFieldValue(field, bean, beanName);                                }                        }                        else {                                value = resolveFieldValue(field, bean, beanName);                        }                        if (value != null) {                                ReflectionUtils.makeAccessible(field);                                field.set(bean, value);                        }                }                private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {                        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);                        desc.setContainingClass(bean.getClass());                        Set autowiredBeanNames = new LinkedHashSet<>(1);                        Assert.state(beanFactory != null, "No BeanFactory available");                        TypeConverter typeConverter = beanFactory.getTypeConverter(); //类型转换器                        Object value;                        try {                                value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);                        }                        catch (BeansException ex) {                                throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);                        }                        synchronized (this) {                                if (!this.cached) {                                        Object cachedFieldValue = null;                                        if (value != null || this.required) {                                                cachedFieldValue = desc;                        // 将注入关系添加到容器中,方便bean销毁时同步销毁                                                registerDependentBeans(beanName, autowiredBeanNames);                                                if (autowiredBeanNames.size() == 1) {                                                        String autowiredBeanName = autowiredBeanNames.iterator().next();                                                        if (beanFactory.containsBean(autowiredBeanName) &&                                                                        beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { //这些都是为了缓存起来                                                                cachedFieldValue = new ShortcutDependencyDescriptor(                                                                                desc, autowiredBeanName, field.getType());                                                        }                                                }                                        }                                        this.cachedFieldValue = cachedFieldValue;                                        this.cached = true;                                }                        }                        return value;                }        }

主要核心是如从缓存获取到需要注入类型实例在beanFactory.resolveDependency中 进入DefaultListableBeanFactory看下

  public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,                        @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {                descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());                if (Optional.class == descriptor.getDependencyType()) {                        return createOptionalDependency(descriptor, requestingBeanName);                }                else if (ObjectFactory.class == descriptor.getDependencyType() ||                                ObjectProvider.class == descriptor.getDependencyType()) {                        return new DependencyObjectProvider(descriptor, requestingBeanName);                }                else if (javaxInjectProviderClass == descriptor.getDependencyType()) {                        return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);                }                else {                        //懒加载  扫描@Lazy注解,返回一个代理对象                        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(                                        descriptor, requestingBeanName);                        if (result == null) {                                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);                        }                        return result;                }        }

@Lazy 使用注解修饰bean 或者Class,在容器初始化化时不会立刻创建,只要需要使用bean才会创建的。 根据类型Optional、ObjectFactory、Provider,还有懒加载情景不同的处理,这些处理本质都是要调用doResolveDependency方法初始化对象,无论那种对象都要 获取原始对象然后再交给这些接口去包装增强。

   public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,                        @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {            //如果这个注入是通过构造器注入,可以从构造器解析缓存中去获取注入信息点                    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);                try {                        Object shortcut = descriptor.resolveShortcut(this);                        if (shortcut != null) {                                return shortcut;                        }                        Class type = descriptor.getDependencyType();                     //尝试从注解中获取默认值   @Value  的value                          Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);                        if (value != null) {                                if (value instanceof String) {                                        String strVal = resolveEmbeddedValue((String) value);                                        BeanDefinition bd = (beanName != null && containsBean(beanName) ?                                                        getMergedBeanDefinition(beanName) : null);                                        value = evaluateBeanDefinitionString(strVal, bd);                                }                                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());                                try {                                        return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());                                }                                catch (UnsupportedOperationException ex) {                                        // A custom TypeConverter which does not support TypeDescriptor resolution...                                        return (descriptor.getField() != null ?                                                        converter.convertIfNecessary(value, type, descriptor.getField()) :                                                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));                                }                        }              //多种混合类型处理,stream、collection、Map Array 这些                        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);                        if (multipleBeans != null) {                                return multipleBeans;                        }                  //根据类型获取容器中bean名,返回map key就是bean名,value 初始从容器中获取对象,如果没有找到就会抛出异常了                        Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);                        if (matchingBeans.isEmpty()) {                                if (isRequired(descriptor)) {                                        raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);                                }                                return null;                        }                        String autowiredBeanName;                        Object instanceCandidate;                        if (matchingBeans.size() > 1) {  //出现一个类型,不同实例,可以根据@Primary, @Priority、属性名方式去配置                                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);                                if (autowiredBeanName == null) {                                        if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {  //没有确定,抛出异常                                                return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);                                        }                                        else {                                                return null;                                        }                                }                                instanceCandidate = matchingBeans.get(autowiredBeanName);                        }                        else {                                // We have exactly one match.                                Map.Entry entry = matchingBeans.entrySet().iterator().next();                                autowiredBeanName = entry.getKey();                                instanceCandidate = entry.getValue();                        }                        if (autowiredBeanNames != null) {                                autowiredBeanNames.add(autowiredBeanName);                        }                        if (instanceCandidate instanceof Class) {  //这里其实就是从容器中获取实例,如果这时候没有初始化,就走上面初始化流程                                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);                        }                        Object result = instanceCandidate;                        if (result instanceof NullBean) {                                if (isRequired(descriptor)) {                                        raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);                                }                                result = null;                        }                        if (!ClassUtils.isAssignableValue(type, result)) {                                throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());                        }                        return result;                }                finally {                        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);                }        }

这个方法简单做个总结,先是处理 @Value 情况,然后通过findAutowireCandidates 通过类型去容器中获取实例,如何实例还没有初始化,就会调用上面那个初始化过程,将初始化对象返回。根据注入类型进行相应处理,像stream、Collection,这些混合类型都是直接添加进去。如果出现了一个类型多个bean情况,这时就是就是@Primary、@Priority这些注解来判断或者根据属性名去和beanName匹配,最后将bean对象返回。 这里就简单看完一个bean初始化流程了。

以上是"Spring Bean怎么初始化"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0