spring-Bean实例初始化的源码initializeBean和应用说明

前言

springBean对象的初始化,是在其进行属性赋值后,在AbstractAutowireCapableBeanFactoryinitializeBean 方法执行的动作:

整个初始化流程如下

  • 1:执行BeanNameAwaresetBeanName方法
  • 2:执行BeanClassLoaderAwaresetBeanClassLoader方法
  • 3:执行BeanFactoryAwaresetBeanFactory方法
  • 4: 执行后置处理器BeanPostProcessorpostProcessBeforeInitialization方法
  • 5: 调用InitializingBean接口初始化 (如果配置了method-init,则调用其方法初始化 )
  • 4: 执行后置处理器BeanPostProcessorpostProcessAfterInitialization方法

源码分析

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

		// 第一步:先执行所有的AwareMethods,具体如下代码,比较简单
		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()) {
			// 执行所有的BeanPostProcessor#postProcessBeforeInitialization  初始化之前的处理器方法
			// 规则:只要谁反回了null,后面的就都不要执行了
			// 这里面实现postProcessBeforeInitialization 的处理器就很多了,有很多对Aware进行了扩展的,具体如下面的具体介绍吧
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
			// 备注:这里initMethod方法的名称不能是afterPropertiesSet,并且这个类不是 InitializingBean类型才会调用,需要特别注意。
			//(然后该方法只有方法名,所以肯定是反射调用,效率稍微低那么一丢丢)
			// 由此可以见,实现这个接口的初始化方法,是在标注形如@PostConstruct之后执行的
			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()) {
			// 整个Bean都初始化完成了,就执行后置处理器的这个方法
			// 如果谁反悔了null,后面的处理器都不会再执行了
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

第一步调用相关Aware接口

相关Aware接口为:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 这些都是spring将数据暴露出去的一种方式,我们直接实现这个接口就能拿到了~

  • BeanNameAware:可以将该bean实例的beanName属性注入到该实例中
  • BeanClassLoaderAware:可以向bean中注入加载该bean的ClassLoader
  • BeanFactoryAware:可以将当前的beanFactory注入到该bean实例中
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);
			}
		}
	}

第二步执行后置处理器的postProcessBeforeInitialization方法

  • 规则:只要谁反回了null,后面的就都不要执行了
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

BeanPostProcessor的postProcessBeforeInitialization的重要实现类解释如下:

1、ApplicationContextAwareProcessor

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		//忽略代码........
		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 Aware) {
			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 ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

2、BeanValidationPostProcessor:对bean进行数据校验

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!this.afterInitialization) {
			doValidate(bean);
		}
		return bean;
	}

3、BootstrapContextAwareProcessor

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) {
			((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext);
		}
		return bean;
	}

4、ServletContextAwareProcessor

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (getServletContext() != null && bean instanceof ServletContextAware) {
			((ServletContextAware) bean).setServletContext(getServletContext());
		}
		if (getServletConfig() != null && bean instanceof ServletConfigAware) {
			((ServletConfigAware) bean).setServletConfig(getServletConfig());
		}
		return bean;
	}

5、LoadTimeWeaverAwareProcessor

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof LoadTimeWeaverAware) {
			LoadTimeWeaver ltw = this.loadTimeWeaver;
			if (ltw == null) {
				Assert.state(this.beanFactory != null,
						"BeanFactory required if no LoadTimeWeaver explicitly specified");
				ltw = this.beanFactory.getBean(
						ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class);
			}
			((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw);
		}
		return bean;
	}

6、InitDestroyAnnotationBeanPostProcessor

  • 处理声明周期注解方法的处理器。有了它,就允许用注解代替去实现Spring的接口InitializingBean和DisposableBean了。
  • 比如@PostConstruct和@PreDestroy等
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			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;
	}

第三步执行初始化方法

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		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);
			}
		}
	}

第四步执行后置处理器的postProcessAfterInitialization方法

  • 规则:只要谁反回了null,后面的就都不要执行了
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

BeanPostProcessor的postProcessAfterInitialization的重要类实现解释如下

Aop相关的几个实现,这里先不做解释,等到后面AOP文章会专门解析

1、ApplicationListenerDetector

  • 把所有的ApplicationListener的Bean,都加入到addApplicationListener里面,放到广播器里面
public Object postProcessAfterInitialization(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// singleton bean (top-level or inner): register on the fly
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
							"but is not reachable for event multicasting by its containing ApplicationContext " +
							"because it does not have singleton scope. Only top-level listener beans are allowed " +
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

2、BeanValidationPostProcessor

  • 校验
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (this.afterInitialization) {
			doValidate(bean);
		}
		return bean;
	}

3、ScheduledAnnotationBeanPostProcessor

  • 解析方法中标注有@Scheduled注解的 然后加入当作一个任务进行执行
public Object postProcessAfterInitialization(final Object bean, String beanName) {
		Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
		if (!this.nonAnnotatedClasses.contains(targetClass)) {
			Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
					(MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
						Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
								method, Scheduled.class, Schedules.class);
						return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
					});
			if (annotatedMethods.isEmpty()) {
				this.nonAnnotatedClasses.add(targetClass);
				if (logger.isTraceEnabled()) {
					logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
				}
			}
			else {
				// Non-empty set of methods
				annotatedMethods.forEach((method, scheduledMethods) ->
						scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
				if (logger.isDebugEnabled()) {
					logger.debug(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
							"': " + annotatedMethods);
				}
			}
		}
		return bean;
	}

4、SimpleServletPostProcessor

  • 这个很有意思。 相当于当Servlet是以Bean的形式注入容器的时候,Bean初始化完成后,会自动调用它的init方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof Servlet) {
			ServletConfig config = this.servletConfig;
			//如果config为null,那么它传入可能为代理的DelegatingServletConfig
			if (config == null || !this.useSharedServletConfig) {
				config = new DelegatingServletConfig(beanName, this.servletContext);
			}
			try {
				((Servlet) bean).init(config);
			}
			catch (ServletException ex) {
				throw new BeanInitializationException("Servlet.init threw exception", ex);
			}
		}
		return bean;
}

实际应用:后置处理器

Bean后置处理器对IOC容器的所有Bean实例逐一处理,而非单一实例,它是更加细致的处理bean的生命周期
其典型应用是;检查Bean属性的正确性或根据特定的标准更改Bean的属性
对Bean后置处理器而言,需要实现BeanPostProcessor接口

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

实际应用:对象的初始化和销毁

springBean实例化对象的初始化方法和销毁方法,其实现方法有3种
注意:在懒加载条件下,容器是不会主动调用bena的初始化方法和销毁方法

1、使用@Bean属性

@Configuration
public class CarFactory {
     
     @Bean(initMethod="init",destroyMethod="destory",name="car")
     public Car car(){
           return new Car();
     } 
}

2、使用@PostConstruct(标识这个方法是初始化方法) @PreDestroy(标识这个方法是销毁方法)

public class Car {
     
     @PreDestroy
     public void destroy() throws Exception {
           System.out.println("destory....");
     }

     @PostConstruct
     public void init() throws Exception {
           System.out.println("init....");
     }
}

3、让bean实现InitializingBean和DisposableBean接口

1、InitializingBean

public interface InitializingBean {
     void afterPropertiesSet() throws Exception;//bean在初始化时调用
}

2、DisposableBean

public interface DisposableBean {
     void destroy() throws Exception;//bean在销毁时调用
}
发布了34 篇原创文章 · 获赞 0 · 访问量 1368

猜你喜欢

转载自blog.csdn.net/qq_41071876/article/details/104567703