• 【Spring-5.3】AbstractAutowireCapableBeanFactory#initializeBean实现Bean的初始化


    本篇将分析bean的初始化过程,难度不大。进入正题。。。
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

    第一步:给各个Aware接口赋值

    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    		// 这里有个条件判断,但逻辑都是调用invokeAwareMethods方法,看看里面做了什么
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			invokeAwareMethods(beanName, bean);
    		}
    
    		。。。。。
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    AbstractAutowireCapableBeanFactory#invokeAwareMethods
    实现了各类型的aware接口,赋值。

    	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);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第二步:执行初始化前处理器

    之后调用了BeanPostProcessor的postProcessBeforeInitialization方法。

    Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    • 1
    • 2
    • 3
    • 4

    目前容器中有跟多BeanPostProcessor,有两个重要的需要看下
    ApplicationContextAwareProcessor#postProcessBeforeInitialization

    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
    				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
    				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
    				bean instanceof ApplicationStartupAware)) {
    			return bean;
    		}
    
    		AccessControlContext acc = null;
    
    		if (System.getSecurityManager() != null) {
    			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    		}
    
    		if (acc != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareInterfaces(bean);
    				return null;
    			}, acc);
    		}
    		else {
    			invokeAwareInterfaces(bean);
    		}
    
    		return bean;
    	}
    
    	private void invokeAwareInterfaces(Object bean) {
    		if (bean instanceof EnvironmentAware) {
    			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    		}
    		if (bean instanceof EmbeddedValueResolverAware) {
    			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    		}
    		if (bean instanceof ResourceLoaderAware) {
    			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    		}
    		if (bean instanceof ApplicationEventPublisherAware) {
    			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    		}
    		if (bean instanceof MessageSourceAware) {
    			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    		}
    		if (bean instanceof ApplicationStartupAware) {
    			((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
    		}
    		if (bean instanceof ApplicationContextAware) {
    			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    发现拓展了aware接口,同样是赋值。

    CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization

    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		// 找到声明周期方法即,@PostConstruct,@PreDestroy标注的方法,这里的逻辑不做详细分析了。
    		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    		try {
    			// 执行注解PostConstruct标注的方法。
    			metadata.invokeInitMethods(bean, beanName);
    		}
    		catch (InvocationTargetException ex) {
    			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    		}
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    初始化前处理器主要做两项工作,1.给其他的aware接口赋值;2. 调用注解PostConstruct标注的方法。


    第三步:执行初始化方法

    		try {
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    	protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    			throws Throwable {
    		// 如果这个bean实现了InitializingBean,将调用afterPropertiesSet方法
    		boolean isInitializingBean = (bean instanceof InitializingBean);
    		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    			}
    			if (System.getSecurityManager() != null) {
    				try {
    					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
    						((InitializingBean) bean).afterPropertiesSet();
    						return null;
    					}, getAccessControlContext());
    				}
    				catch (PrivilegedActionException pae) {
    					throw pae.getException();
    				}
    			}
    			else {
    				((InitializingBean) bean).afterPropertiesSet();
    			}
    		}
    		
    		// 如果有设置初始化方法,则调用方法
    		if (mbd != null && bean.getClass() != NullBean.class) {
    			String initMethodName = mbd.getInitMethodName();
    			if (StringUtils.hasLength(initMethodName) &&
    					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    					!mbd.isExternallyManagedInitMethod(initMethodName)) {
    				invokeCustomInitMethod(beanName, bean, mbd);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    主要是调用初始化方法,实现了InitializingBean接口的调用afterPropertiesSet方法,有指定init-method的再调用指定的方法。


    第四步:调用初始化后处理器

    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    • 1
    • 2
    • 3

    这个比较重要的当属AbstractAutoProxyCreator#postProcessAfterInitialization,用来创建代理的。

    总结

    理清方法执行的顺序

    1. 先给aware接口赋值
    2. bean处理器的初始化前处理方法:因为InitDestroyAnnotationBeanPostProcessor实现了PriorityOrdered接口,所以先加载,也就是说现实执行@PostConstruct方法,之后再执行拓展的Aware接口方法
    3. 执行初始化方法afterPropertiesSet,如果设置了init-method,在执行设置的方法。
    4. 最后是初始化后处理器的方法

    bean的初始化顺序参考Spring Bean的生命周期(非常详细),本篇的分析过程可以涵盖为Bean注入属性之后的过程。

    初始化调用顺序:

    1. @PostConstruct方法
    2. spring的初始化接口的afterPropertiesSet方法
    3. xml配置文件bean标签设置的init-method方法

    销毁顺序:则是跟上面的相同

    1. @PreDestroy注解标注的方法
    2. DisposableBean回调接口定义的destroy()
    3. xml配置文件的destroy-method方法
  • 相关阅读:
    数据库搭建和Maven项目环境搭建(瑞吉外卖)
    Pandas-用一个dataframe去更新另一个dateframe
    RPA技术如何重塑制造业的未来
    趋势分析是什么?市场趋势分析的经典方法,从数据中识别机会
    清华美院「后羿雕塑」像外国人,引全网争议.....
    定义和声明
    NFT数字藏品交易平台开发
    Linux:用户态与内核态
    go-gin-vue3-elementPlus带参手动上传文件
    1.ts介绍
  • 原文地址:https://blog.csdn.net/qq_34501351/article/details/118148806