前言
springBean对象的初始化,是在其进行属性赋值后,在AbstractAutowireCapableBeanFactory
的initializeBean
方法执行的动作:
整个初始化流程如下
- 1:执行
BeanNameAware
的setBeanName
方法 - 2:执行
BeanClassLoaderAware
的setBeanClassLoader
方法 - 3:执行
BeanFactoryAware
的setBeanFactory
方法 - 4: 执行后置处理器
BeanPostProcessor
的postProcessBeforeInitialization
方法 - 5: 调用
InitializingBean
接口初始化 (如果配置了method-init
,则调用其方法初始化 ) - 4: 执行后置处理器
BeanPostProcessor
的postProcessAfterInitialization
方法
源码分析
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在销毁时调用
}