1. BeanFactoryPostProcessor
它是BeanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,创建时机是在所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建。
说到BeanFactoryPostProcessor就要提到BeanPostProcessor,其在是Bean的后置处理器,Bean创建对象初始化前后进行拦截工作。
package com.bjc.beanFactoryPostProcessorTest.processor;
import java.util.Arrays;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("进入到BeanFactoryPostProcessor。。。");
// 获取factory中的定义的bean的数量
int count = beanFactory.getBeanDefinitionCount();
System.out.println("有" + count + "已经定义了的bean。");
// 获取所有的bean的名称
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println(Arrays.asList(names));
}
}
测试结果:
从结果可以看出,BeanFactoryPostProcessor的执行是在Bean的创建之前。
2. BeanDefinitionRegistryPostProcessor
该类是BeanFactoryPostProcessor的子类,加载时机是在所有bean定义信息将要被加载,bean实例还未创建的;优先于BeanFactoryPostProcessor执行,可以利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件。
package com.bjc.beanFactoryPostProcessorTest.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import com.bjc.beanFactoryPostProcessorTest.pojo.Blue;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("进入到MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory");
System.out.println("bean的数量:"+beanFactory.getBeanDefinitionCount());
}
//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("进入到MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry");
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
// 给容器中额外的添加组件Blue
//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
运行结果:
可以发现BeanDefinitionRegistryPostProcessor先于BeanFactoryPostProcessor执行,且postProcessBeanDefinitionRegistry方法先于postProcessBeanFactory执行。
3. ApplicationListener
用于监听容器中发布的事件,完成事件驱动模型的开发。其定义为public interface ApplicationListener<E extends ApplicationEvent>,也就是说,如果要实现一个监听器,就需要实现该接口就可以了。泛型就是我们需要的监听 ApplicationEvent 及其下面的子事件。
自定义事件监听器:
package com.bjc.beanFactoryPostProcessorTest.processor;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
// TODO Auto-generated method stub
System.out.println("收到事件:"+event);
}
}
运行如图:
默认会获取两个事件:
1)ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
2)ContextClosedEvent:关闭容器会发布这个事件
我们可以自定义一个事件并发布到spring中么?肯定是可以的。
操作步骤如下:
方式一:
1)写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)。
2)把监听器加入到容器;
3)通过applicationContext.publishEvent()发布事件
测试:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanFactoryPostProcessorConfig.class);
context.publishEvent(new ApplicationEvent("自定义事件监听器") {});
context.close();
}
运行结果:
方式二:
使用注解@EventListener,可以让任意方法成为一个事件监听,其原理是使用EventListenerMethodProcessor处理器来解析方法上的@EventListener
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
Object source = event.getSource();
System.out.println("UserService。。监听到的事件:"+event);
}
}