• spring5.0 源码解析 initializeBean 11


    initializeBean

    spring 在bean的属性注入之后会执行 initializeBean 方法
    该方法主要分为以下几个步骤

    1. 执行 aware 方法
    2. 执行 processor.postProcessBeforeInitialization
    3. 执行 Init-Methods
    4. 执行 processor.postProcessAfterInitialization

    invokeAwareMethods

    如果 bean 实现了相应的 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

    applyBeanPostProcessorsBeforeInitialization

    在初始化之前执行 的 BeanPostProcessors

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    			throws BeansException {
    
    		Object result = existingBean;
    		// 获取所有的 BeanPostProcessor 循环执行 
    		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    			Object current = processor.postProcessBeforeInitialization(result, beanName);
    			if (current == null) {
    				return result;
    			}
    			result = current;
    		}
    		return result;
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    spring 实现处理器
    spring 实现处理器

    1. ApplicationContextAwareProcessor
      可以让bean感知到上下文,也是为bean注入容器相关属性的方法
      如果bean实现了相关的aware 那么则会在invokeAwareInterfaces方法中设置相关属性

      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;
      	}
      
      • 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
    2. InitDestroyAnnotationBeanPostProcessor
      主要完成了 对 @PostConstruct 注解方法的回调;

    这个处理器在before init 之前并没有做什么操作

    public Object postProcessBeforeInitialization(Object bean, String beanName) {
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    1. ConfigurationClassPostProcessor
      这个 PostProcessor 很复杂 先一放
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
    			if (bean instanceof ImportAware) {
    				ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
    				AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
    				if (importingClass != null) {
    					((ImportAware) bean).setImportMetadata(importingClass);
    				}
    			}
    			return bean;
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    invokeInitMethods

    执行 Init-Methods 初始化 implements InitializingBean 所设置的属性

    如果bean 实现了 InitializingBean 则调用 InitializingBean
    没有实现则调用 init-Method

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    			throws Throwable {
    
    		boolean isInitializingBean = (bean instanceof InitializingBean);
    		//  InitializingBean中 的 init 回调函数名 afterPropertiesSet 会在这里记录ExternallyManagedInitMethod 中,以便进行生命周期回调
    		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();
    			}
    		}
    		// 如果不存在  在给定bean上调用指定的自定义init方法。
    		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

    applyBeanPostProcessorsAfterInitialization

    在初始化之后执行 的 BeanPostProcessors

    eanPostProcessorbefore方法after方法
    ApplicationContextAwareProcessor为​​EnvironmentAware​​​、​​EmbeddedValueResolverAware​​​、​​ResourceLoaderAware​​​、​​ApplicationEventPublisherAware​​​、​​MessageSourceAware​​​及​​ApplicationContextAware​​设置信息没有实现,默认返回bean
    WebApplicationContextServletContextAwareProcessor父类ServletContextAwareProcessor,为ServletContextAware设置ServletContext;为ServletConfigAware设置ServletConfig直接返回bean
    ImportAwareBeanPostProcessorConfigurationClassPostProcessor的内部类,为ImportAware设置ImportMetadata直接返回bean
    ConfigurationPropertiesBindingPostProcessor使用ConfigurationPropertiesBinder将ProterySource与配置​@ConfigurationProperties​​ Bean进行绑定
    AnnotationAwareAspectJAutoProxyCreator父类AbstractAutoProxyCreator,直接返回bean父类AbstractAutoProxyCreator方法,对bean尝试进程代理直接返回bean
    DataSourceInitializerPostProcessor直接返回bean当实例化DataSourceh时,启动DataSourceInitializerInvoker的实例化
    MethodValidationPostProcessor父类AbstractAdvisingBeanPostProcessor,直接返回bean父类AbstractAdvisingBeanPostProcessor,尝试将当前advisor添加
    PersistenceExceptionTranslationPostProcessor父类AbstractAdvisingBeanPostProcessor,直接返回bean父类AbstractAdvisingBeanPostProcessor,尝试将当前advisor添加到当前bean的Advisor链上
    CommonAnnotationBeanPostProcessor父类InitDestroyAnnotationBeanPostProcessor,反射调用初始化方法,如加了注解@PostConstruct的方法直接返回Bean
    AutowiredAnnotationBeanPostProcessor父类InstantiationAwareBeanPostProcessorAdapter直接返回bean父类InstantiationAwareBeanPostProcessorAdapter直接返回bean
    ApplicationListenerDetector返回bean如果当前bean是ApplicationListener且是单例的,尝试注册到applicationContext中

    return wrappedBean;

    返回 wrappedBean对象

    Initializing与 Disposable 执行顺序

    关于在Spring 容器 初始化和销毁 bean 前所做的操作有三种方式定义:

    通过@PostConstruct 和 @PreDestroy 方法 实现初始化后和销毁bean之前进行的操作

    通过bean实现InitializingBean和 DisposableBean接口

    通过 在xml中配置init-method 和 destory-method方法,或者 配置@Bean(initMethod = “initMethod”, destroyMethod = “destroyMethod”) 注解

  • 相关阅读:
    Web服务(03)——HTTP协议
    【洛谷 B2003】输出第二个整数 题解(顺序结构+输入输出)
    Unity --- UI图像,锚点与轴心点
    学习vue-unit.md单元测试
    共享充电宝APP前端设计和实现
    C 语言数组
    GIS前端编程-Leaflet插件扩展
    【Java】已解决:Java.lang.OutOfMemoryError: GC overhead limit exceeded
    【机器学习】梯度下降算法原理和实现
    猫头虎分享已解决Bug || Null Pointer Exception: `java.lang.NullPointerException`
  • 原文地址:https://blog.csdn.net/qq_44808472/article/details/126214706