- 前面知道BeanPostProcessor是bean后置处理器,bean创建对象初始化前后进行拦截工作的,下面将介绍几种重要的类和接口。
1、BeanFactoryPostProcessor
- beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;此时所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建。
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
//当前容器中定义的bean个数
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
- 原理
查看AbstractApplicationContext.refresh方法中的有这么一段代码,
invokeBeanFactoryPostProcessors(beanFactory),这里面主要做了找到所有的BeanFactoryPostProcessor,并执行他们的方法。特点:
1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
2)、在初始化创建其他组件前面执行 - invokeBeanFactoryPostProcessors(beanFactory)中
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
- invokeBeanFactoryPostProcessors中
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
2、BeanDefinitionRegistryPostProcessor
- 继承于BeanFactoryPostProcessor,优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
}
//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
- 原理:
原理:
1)、ioc创建对象
2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
1、依次触发所有的postProcessBeanDefinitionRegistry()方法
2、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法
- invokeBeanFactoryPostProcessors(beanFactory)方法中
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
//触发postProcessBeanDefinitionRegistry方法
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//然后触发postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
3、ApplicationListener
- spring监听容器中发布的事件。事件驱动模型开发
- 源码:
//是一个函数式接口
//用于监听 ApplicationEvent 及其下面的子事件
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends
EventListener {
void onApplicationEvent(E event);
}
- 使用案例:
步骤:
1)、写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
@EventListener;原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener
2)、把监听器加入到容器;
3)、只要容器中有相关事件的发布,我们就能监听到这个事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发布这个事件;
4)、发布一个事件:
applicationContext.publishEvent();
实例:
1、自定义事件监听器
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件:"+event);
}
}
--》测试:
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(ExtConfig.class);
//关闭容器
applicationContext.close();
}
/*
在容器中注册后测试,结果是:
收到事件:org.springframework.context.event.ContextRefreshedEvent...
收到事件:org.springframework.context.event.ContextClosedEvent...
其中:
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发布这个事件;
*/
2、在测试中自己发布事件或自定义一个事件发布器
//发布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {});
//测试结果:
收到事件:com.huya.qiu.ext.IOCTest_Ext$1[source=我发布的时间]
- spring监听器原理:
(1)事件的执行顺序:
事件的执行顺序:
1)、ContextRefreshedEvent事件:
1)、容器创建对象:refresh();
2)、finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件
2)、自己发布事件;
3)、容器关闭会发布ContextClosedEvent;
(2)事件发布的流程源码解读:
事件发布的流程源码解读:
1、AnnotationConfigApplicationContext构造器里面的refresh方法
2、AbstractApplicationContext.refresh方法里面的finishRefresh();方法
3、AbstractApplicationContext.finishRefresh方法里面的publishEvent方法
4、在publishEvent中获取ApplicationEventMulticaster事件多发器,并执行事件多发器的
multicastEvent方法,也就是将给定的应用程序事件广播到适当的监听器,该方法如下:
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//遍历容器中定义的事件监听器
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//如果有异步的事件监听器就调用异步的事件监听器
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
//调用事件监听器
invokeListener(listener, event);
}
}
}
5、调用invokeListener(ApplicationListener listener, ApplicationEvent event)方法
protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
listener.onApplicationEvent(event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
try {
//处理监听器监听到的事件
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
LogFactory.getLog(getClass()).debug("Non-matching event type for listener: " + listener, ex);
}
}
}
(3)事件多播器(派发器)的创建
1、AnnotationConfigApplicationContext构造器里面的refresh方法
2、里面的initApplicationEventMulticaster();为容器初始化事件多发器
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//先去容器中找有没有id=“applicationEventMulticaster”的组件;
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
(4)容器中注册相应的事件监听器
1、AnnotationConfigApplicationContext构造器里面的refresh方法
2、里面的registerListeners();效验监听器并把他们注册到容器中
protected void registerListeners() {
//从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//根据类型获取容易中多有注册的监听器,并注册到容器中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
- 采用注解的形式来扩展监听器的使用(也就说更加方便而不需实现接口了)
1、@EventListener原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener
2、案例
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。监听到的事件:"+event);
}
}
3、解析原理源码解读
(1)EventListenerMethodProcessor处理器
//实现了SmartInitializingSingleton接口和ApplicationContextAware接口
public class EventListenerMethodProcessor implements SmartInitializingSingleton
, ApplicationContextAware
(2)SmartInitializingSingleton 接口
public interface SmartInitializingSingleton {
//在所有的单实例都完成初始化后触发
void afterSingletonsInstantiated();
}
(3)出发原理
1)ioc容器创建对象并refresh();
2)finishBeanFactoryInitialization(beanFactory)方法,初始化剩下的单实例bean;
3)beanFactory.preInstantiateSingletons();初始化剩下的单实例bean;
*先创建所有的单实例bean;getBean()
*获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();
4)smartSingleton.afterSingletonsInstantiated()
public void afterSingletonsInstantiated() {
List<EventListenerFactory> factories = getEventListenerFactories();
String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
Class<?> type = null;
try {
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(), beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
}
}
if (type != null) {
if (ScopedObject.class.isAssignableFrom(type)) {
try {
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(),
ScopedProxyUtils.getTargetBeanName(beanName));
}
catch (Throwable ex) {
// An invalid scoped proxy arrangement - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
}
}
}
try {
//获取实例bean的@EventListener并注册并在容器中注册该监听器
processBean(factories, beanName, type);
}
catch (Throwable ex) {
throw new BeanInitializationException("Failed to process @EventListener " +
"annotation on bean with name '" + beanName + "'", ex);
}
}
}
}
}