在bean的配置中有一个init-method的属性,这个属性的作用是在bean实例化前调用init-method指定的方法来根据业务进行相应的实例化,当程序执行到初始化bean的代码逻辑时,说明bean已经实例化完成,且已经进行了属性注入。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//对特殊的bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用后置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}try {
//激活用户的自定义的init方法
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;
}
一、激活Aware方法
Spring中提供了一些Aware的接口,比如BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware等。实现这些Aware的接口的bean在被初始化之后,可以取得一些相对应的资源。例如实现BeanFactoryAware的bean在初始化之后,spring容器会注入BeanFactory的实例,而实现ApplicationContextAware的bean,在bean被初始化后,将会被注入ApplicationContext的实例。
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)的应用
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; }
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
三、激活自定义init方法
自定义用户init初始化方法有2种
1、init-method(优先级低)
2、实现InitializingBean接口覆写afterPropertiesSet方法(优先级高)
、、