1 Aware接口
1.1 Aware 是什么
Aware 是一个空接口,方法签名交由其子接口实现,一般来说,其子接口只有一个setXXX 的方法
ApplicationContextAware->setApplicationContextBeanNameAware->setBeanName
在前文中的spring 初始化中也有相关的代码
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
// BeanNameAware -> setBeanName
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoaderAware -> setBeanClassLoader
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// BeanFactoryAware -> setBeanFactory
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
1.2 子接口
其子接口何其多啊
我们举个简单的例子 BeanNameAware
package org.springframework.beans.factory;
public interface BeanNameAware extends Aware {
void setBeanName(String var1);
}
1.3 演示
@Component
public class MyAwareTest implements BeanNameAware, BeanClassLoaderAware {
String beanName;
ClassLoader beanClassLoader;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("调用了 MyAwareTest 的 setBeanClassLoader");
this.beanClassLoader = beanClassLoader;
}
@Override
public void setBeanName(String name) {
System.out.println("调用了 MyAwareTest 的 setBeanName");
beanName = beanName;
}
}
@SpringBootApplication
public class CustomerServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext cx = (ConfigurableApplicationContext) SpringApplication.run(CustomerServiceApplication.class, args);
MyAwareTest beanTest = (MyAwareTest) cx.getBean("myAwareTest");
}
输出结果为
调用了 MyAwareTest 的 setBeanName
调用了 MyAwareTest 的 setBeanClassLoader
2BeanPostProcessor接口
作用:在bean完成实例化后对其进行增强和配置
2.1 使用示例
@Component
public class BeanPostProcessorTest implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean " + beanName + " 调用了 postProcessBeforeInitialization");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean " + beanName + " 调用了 postProcessAfterInitialization");
return bean; }
}
@SpringBootApplication
public class CustomerServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext cx = (ConfigurableApplicationContext) SpringApplication.run(CustomerServiceApplication.class, args);
BeanPostProcessorTest beanTest = (BeanPostProcessorTest) cx.getBean("beanPostProcessorTest");
}
}
打印日志
bean connManFactory 调用了 postProcessBeforeInitialization
bean connManFactory 调用了 postProcessAfterInitialization
bean apacheHttpClientFactory 调用了 postProcessBeforeInitialization
bean apacheHttpClientFactory 调用了 postProcessAfterInitialization
bean org.springframework.cloud.commons.httpclient.HttpClientConfiguration 调用了 postProcessBeforeInitialization
bean org.springframework.cloud.commons.httpclient.HttpClientConfiguration 调用了 postProcessAfterInitialization
代码植入点
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
看到这里胖友们是不是觉得很简单,那如果我们换一个代码,还会出现一样的日志吗?
ClassPathResource resource = new ClassPathResource("spring.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
BeanPostProcessorTest test = (BeanPostProcessorTest) factory.getBean("beanPostProcessorTest");
答案是否定的,因为普通的 BeanFactory 是不会实现 BeanPostProcessor的字段注册的
factory.addBeanPostProcessor(beanPostProcessorTest);这种方法进行注册,ApplicationContext可以在其 bean 定义中自动检测所有的 BeanPostProcessor 并自动完成注册,同时将他们应用到随后创建的任何 Bean 中
2.2 原理
BeanPostProcessor 接口源码
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanPostProcessor 可以理解为Spring钩子(Aware 也是),开发人员可以在对象实例化的时候进行扩展,流程图如下
2.2.1 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);
}
2.2.2 源码applyBeanPostProcessorsBeforeInitialization 源码
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
//遍历 beanPostProcessors
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 处理
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
2.2.3 源码applyBeanPostProcessorsAfterInitialization 源码
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
2.3 ApplicationContext 如何实现自动注册
getBeanPostProcessors()返回的是所有 BeanPostProcessor 的集合,ApplicationContext之所以能够实现自动注册,是因为Spring在构造ApplicationContext 对象的时候会自动调用registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) ,将检测到的所有BeanPostProcessor 注入进去
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有的 BeanPostProcessor 的 beanName(已经加载到容器中,但未实例化)
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 记录所有的beanProcessor数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 注册 BeanPostProcessorChecker,它主要是用于在 BeanPostProcessor 实例化期间记录日志
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 使用 Ordered 保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
// 没有顺序
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 调用 getBean 获取 bean 实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 有序 Ordered
orderedPostProcessorNames.add(ppName);
} else {
// 无序
nonOrderedPostProcessorNames.add(ppName);
}
}
// 第一步,注册所有实现了 PriorityOrdered 的 BeanPostProcessor
// 先排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 后注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 第二步,注册所有实现了 Ordered 的 BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 先排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 后注册
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 第三步注册所有无序的 BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册,无需排序
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,注册所有的 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 加入ApplicationListenerDetector(探测器)
// 重新注册 BeanPostProcessor 以检测内部 bean,因为 ApplicationListeners 将其移动到处理器链的末尾
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
sortPostProcessors 方法
PostProcessorRegistrationDelegate.sortPostProcessors
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// 获得 Comparator 对象
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) { // 依赖的 Comparator 对象
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) { // 默认 Comparator 对象
comparatorToUse = OrderComparator.INSTANCE;
}
// 排序
postProcessors.sort(comparatorToUse);
}
registerBeanPostProcessors 方法
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
// 遍历 BeanPostProcessor 数组,注册
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
BeanPostProcessor是容器级别ApplicationContext可以实现BeanPostProcessor的自动注册,BeanFactory需要手动调用AbstractBeanFactory.addBeanPostProcessorApplicationContext可以实现BeanPostProcessor的自定排序,BeanFactory只和注册顺序有关
3InitializingBean 和init-method
InitializingBean 接口为bean 提供了初始化功能,具体源码如下
public interface InitializingBean {
/**
* 该方法在 BeanFactory 设置完了所有属性之后被调用,允许 bean 实例设置了所有 bean 属性时执行初始化工作,如果该过程出现了错误则需要抛出异常
*/
void afterPropertiesSet() throws Exception;
}
3.1 案例
@Component
@Data
public class InitializingBeanTest implements InitializingBean {
String beanName;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用 InitializingBeanTest 的方法 afterPropertiesSet" );
this.beanName ="naonao";
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
}
@SpringBootApplication
public class CustomerServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext cx = (ConfigurableApplicationContext) SpringApplication.run(CustomerServiceApplication.class, args);
InitializingBeanTest beanTest = (InitializingBeanTest) cx.getBean("initializingBeanTest");
System.out.println(beanTest.getBeanName());;
}
}
输出
beanName is naonao
示例中改变了beanName的名字,那么究竟是在哪里做的改动呢?答案是AbstractAutowireCapableBeanFactory.invokeInitMethods``
3.2 方法 invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
// 首先会检查是否是 InitializingBean ,如果是的话需要调用 afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
//日志代码
}
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) {
// 判断是否指定了 init-method(),
// 如果指定了 init-method(),则再调用制定的init-method
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 激活用户自定义的初始化方法
// 利用反射机制执行
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
- 检测当前 bean 是否实现了
InitializingBean接口,如果实现了则调用其afterPropertiesSet()方法。 - 检查是否也指定了
init-method如果指定了则通过反射机制调用指定的init-method方法。
3.3 方法init-method
init-method 的作用和InitializingBean 作用一致,只不过是配置在 xml文件里,这里就不多做赘述了
3.4 销毁
与之对应的还有DisposableBean 和destroy-method
4 容器扩展机制 BeanFactoryPostProcessor
BeanFactoryPostProcessor 是一种容器扩展机制,作用于容器启动阶段,可以让开发者在容器对bean实例化之前对注册到容器的BeanDefinition进行更改 源码如下
public interface BeanFactoryPostProcessor {
/**
*1、Modify the application context's internal bean factory after its standard initialization.
*
* 2、All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
postProcessBeanFactory()的作用:在BeanDefinition完成加载之后,Bean 实例化之前 对加载BeanDefinition进行修改。BeanFactoryPostProcessor操作的是BeanDefinition,BeanPostProcessor操作的是bean,2者有着本质的不同,千万不能混为一谈。而且BeanFactoryPostProcessor也支持排序
4.1 案例
@Component
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("调用 BeanFactoryPostProcessorTest postProcessBeanFactory");
System.out.println("容器中的个数 " + beanFactory.getBeanDefinitionCount());
BeanDefinition bd = beanFactory.getBeanDefinition("myAwareTest");
MutablePropertyValues propertyValues = bd.getPropertyValues();
propertyValues.add("beanName", "王小闹");
}
@Override
public int getOrder() {
return 1;
}
}
@Component
public class BeanFactoryPostProcessorTes2 implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("调用 BeanFactoryPostProcessorTest postProcessBeanFactory");
System.out.println("容器中的个数 " + beanFactory.getBeanDefinitionCount());
BeanDefinition bd = beanFactory.getBeanDefinition("myAwareTest");
MutablePropertyValues propertyValues = bd.getPropertyValues();
propertyValues.add("beanName", "王小闹2");
}
@Override
public int getOrder() {
return 2;
}
}
@SpringBootApplication
public class CustomerServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext cx = (ConfigurableApplicationContext) SpringApplication.run(CustomerServiceApplication.class, args);
MyAwareTest beanTest = (MyAwareTest) cx.getBean("myAwareTest");
System.out.println("beanName is " +beanTest.getBeanName());;
}
}
4.2 小结
BeanFactoryPostProcessor 和BeanPostProcessor 一样,会被ApplicationContext 自动识别并注册,但是BeanFactory 要手动注册