栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【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) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		。。。。。
	}
 

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);
			}
		}
	}

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

之后调用了BeanPostProcessor的postProcessBeforeInitialization方法。

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

目前容器中有跟多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) () -> {
				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);
		}
	}
 

发现拓展了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.给其他的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);
		}
	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) () -> {
						((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);
			}
		}
	}
 

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


第四步:调用初始化后处理器
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

这个比较重要的当属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方法
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号