spring源码bean生命周期篇 四 bean 初始化

文章详细阐述了Spring框架中bean的初始化过程,包括Aware接口的调用、BeanPostProcessor的作用,特别是@PostConstruct注解的方法执行,以及在不同阶段如何处理配置和AOP相关的内容。
摘要由CSDN通过智能技术生成

在这里插入图片描述

初始化流程概要

1.invokeAwareMethods

(1)BeanNameAware.setBeanName

(2)BeanClassLoaderAware.setBeanClassLoader

(3)BeanFactoryAware.setBeanFactory

2.接着调用BeanPostProcessor.postProcessBeforeInitialization方法

(1) org.springframework.context.support.ApplicationContextAwareProcessor

  • EnvironmentAware.setEnvironment
  • EmbeddedValueResolverAware.setEmbeddedValueResolver
  • ResourceLoaderAware.setResourceLoader
  • ApplicationEventPublisherAware.setApplicationEventPublisher
  • MessageSourceAware.setMessageSource
  • ApplicationContextAware.setApplicationContext

(2) org.springframework.web.context.support.ServletContextAwareProcessor

  • ServletContextAware.setServletContext
  • ServletConfigAware.setServletConfig

(3) org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

  • ImportAware.setImportMetadata

(4) org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor

  • 与@ConfigurationProperties 和Validated注解相关,感兴趣可观看

(5) org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor

if (bean instanceof WebServerFactory) {
			WebServerFactoryCustomizercustomize(((WebServerFactory) bean);
}

(6) org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

  • 调用@PostConstruct注解作用的方法

(7) org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer.PropertyMappingCheckBeanPostProcessor

  • @Component和@PropertyMapping注解的处理

(8)....

3.调用初始化方法

(1) 当前 bean 实现了 InitializingBean 会调用InitializingBean.afterPropertiesSet()方法

  • 但是@PostConstruct修饰的方法名称为afterPropertiesSet不会调用InitializingBean.afterPropertiesSet()方法

(2)@Bean的initMethod属性如果定义了初始化方法名称,也会调用

  • 但是如果Bean的initMethod属性定义的初始化名称为afterPropertiesSet
  • 当前bean实现了InitializingBean接口
  • @PostConstruct修饰的方法名称为afterPropertiesSet

    这三种情况都不会调用Bean的initMethod属性定义的初始化方法

4.初始化

(1) org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

  • 与AOP有关

(2) org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor

  • 与AOP有关

(3)org.springframework.context.support.ApplicationListenerDetector

applicationContext.addApplicationListener((ApplicationListener) bean)

源码解说

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			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()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
1.invokeAwareMethods
  当前bean实现了,**Aware接口调用其实现方法
private void invokeAwareMethods(final String beanName, final 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);
			}
		}
	}
2.调用BeanPostProcessor.postProcessBeforeInitialization方法
调用@PostConstruct修饰的方法(包含父类)

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor


 class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor


   public CommonAnnotationBeanPostProcessor() {
         //定义bean初始化方法需要的注解
		setInitAnnotationType(PostConstruct.class);
		 //定义bean销毁方法需要的注解
		setDestroyAnnotationType(PreDestroy.class);
    }
  
   
     @Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	    //找出bean所有@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;
	}
	
 private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
  //缓存找出的bean所有@PostConstruct注解和(PreDestroy注解的方法,有缓存数据,从缓存数据中获取,没有才会解析
		if (this.lifecycleMetadataCache == null) {
			return buildLifecycleMetadata(clazz);
		}

		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
		if (metadata == null) {
			synchronized (this.lifecycleMetadataCache) {
				metadata = this.lifecycleMetadataCache.get(clazz);
				if (metadata == null) {
					metadata = buildLifecycleMetadata(clazz);
					this.lifecycleMetadataCache.put(clazz, metadata);
				}
				return metadata;
			}
		}
		return metadata;
	}	
怎么找出@PostConstruct注解修饰的方法和@DestoryConstruct方法

不仅仅会获取当前Class的@PostConstruct注解修饰的方法和@DestoryConstruct方法,还会依次递归获取父类的。但是在当前环节只调用@PostConstruct注解修饰的方法

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		List<LifecycleElement> initMethods = new ArrayList<>();
		List<LifecycleElement> destroyMethods = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<LifecycleElement> currInitMethods = new ArrayList<>();
			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
					if (logger.isTraceEnabled()) {
						logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
					}
				}
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
					currDestroyMethods.add(new LifecycleElement(method));
					if (logger.isTraceEnabled()) {
						logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
					}
				}
			});

			initMethods.addAll(0, currInitMethods);
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return new LifecycleMetadata(clazz, initMethods, destroyMethods);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值