共计 3024 个字符,预计需要花费 8 分钟才能阅读完成。
Spring 框架之所以 NB,BeanPostProcessor 功不可没。BeanPostProcessor 通过生命周期回调实现对 Bean 的加强比方,其实 Spring 的 AOP 性能次要就是通过 BeanPostProcessor 实现的,以及,Spring 重要的主动拆卸性能,也是通过 BeanPostProcessor 实现的。
BeanPostProcessor 失效原理
BeanPostProcessor 指的是 Spring 容器中所有实现了 BeanPostProcessor 接口的类,通过如下形式失效:
- BeanPostProcessor 注册:所有实现了 BeanPostProcessor 接口的类,在 Spring 初始化过程中注册到 Spring 容器中
- Bean 生命周期的初始化前、后,Spring 别离回调 BeanPostProcessor 接口的 postProcessBeforeInitialization、postProcessAfterInitialization,从而实现对 bean 的加强。
具体的回调过程,在 AbstractAutowireCapableBeanFactory 的 initializeBean 办法中:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {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()) {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);
}
return wrappedBean;
}
beanPostProcessor 的注册
Spring 初始化时,refresh() 办法中注册 beanPostProcessor:
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
...
registerBeanPostProcessors 办法负责注册 beanPostProcessors, 所有以后容器中实现了 BeanPostProcessor 接口的类,依照如下程序顺次注册到容器的 beanPostProcessors 中:
- 首先,实现了 PriorityOrdered 接口的 BeanPostProcessor
- 其次,实现了 Ordered 接口的 BeanPostProcessor
- 最初,其余一般 BeanPostProcessor
这样,所有的 BeanPostProcessor 就会在 bean 实例化、初始化之前的 Spring 启动阶段注册到 Spring 容器中。之后的 Bean 初始化过程中,Spring 会主动查看所有的 BeanPostProcessor,并顺次回调两个接口办法从而实现 BeanPostProcessor 对 bean 的加强。
此外,还能够通过编程的形式注册 BeanPostProcessor:通过 ConfigurableBeanFactory 的 addBeanPostProcessor 办法注册,编程形式注册的 BeanPostProcessor 优先于 Spring 主动注册的 BeanPostProcessor,并且,编程形式注册的状况下 BeanPostProcessor 的程序与 BeanPostProcessor 的 Ordered 接口无关、仅与注册先后顺序无关。
AOP 与 BeanPostProcessor
因为 Spring AOP 就是通过 BeanPostProcessor 实现代理对象的主动创立的,所以,如果一个 AOP 对象同时实现了 BeanPostProcessor 接口,该对象的 AOP 性能就没有方法实现,因为该 AOP 对象在 Spring 启动的过程中作为 BeanPostProcessor 被注册到 Spring 容器中,与实现 AOP 动静代理的 BeanPostProcessor 是处于同一级别的、从而不会被 AOP 的 BeanPostProcessor 加强,因而也就无奈实现 AOP。
同时,须要留神的是,如果你通过 @Autowired 或 @Resource 主动拆卸你的 BeanPostProcessor 类,在没有指定 bean name 的状况下,有可能会产生不可意料的后果,因为主动拆卸过程中,如果不能通过 name 匹配到 bean,Spring 会依据 type 主动匹配,因为容器中有很多 BeanPostProcessor,所以,可能就会产生错乱 ……
上一篇 Spring FrameWork 从入门到 NB – 定制 Bean