Spring注解驱动开发系列:
Spring注解驱动开发6:Spring扩展原理
BeanFactoryPostProcessor
例子
编写MyBeanFactoryPostProcessor类如下:
@Repository
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor....invoke");
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
System.out.println("总共有:" + beanDefinitionCount);
System.out.println("分别是:");
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
编写配置类代码如下:
//配置类==配置文件
@Configuration
//开启自动包扫描,传入要扫描的包路径
@ComponentScan(basePackages = "com.lin.springL")
public class MainConfigure {
}
编写测试类代码如下:
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConfigure.class);
}
}
运行得到结果:
MyBeanFactoryPostProcessor....invoke
总共有:8
分别是:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigure
myBeanFactoryPostProcessor
在容器初始化的时候就会执行,具体执行过程可以查看我的Spring源码篇。
唯一要关注的是,执行BeanFactoryPostProcessor的时候,这时候BeanFactory只有Bean的定义BeanDefinition,还没有初始化Bean。
具体调用链,可以通过Debug直接查看:
最终的具体细节就是对所有的BeanFactoryPostProcessor遍历执行:
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
BeanDefinitionRegistryPostProcessor
Bean定义信息注册器的后置处理器,实现了BeanFactoryPostProcessor接口,与其不同的是:
- BeanFactoryPostProcessor是在Bean的定义信息加载完后执行,而BeanDefinitionRegistryPostProcessor是在bean定义信息正要加载的时候执行。
例子
编写MyBeanDefinitionRegistryPostProcessor类:
@Repository
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor----postProcessBeanDefinitionRegistry");
//可以在这里创建自己的BeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Lin.class);
registry.registerBeanDefinition("lin", rootBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor----postProcessBeanFactory");
}
}
更改MainTest如下:
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConfigure.class);
Lin bean = applicationContext.getBean(Lin.class);
System.out.println(bean);
}
}
运行得到结果:
MyBeanDefinitionRegistryPostProcessor----postProcessBeanDefinitionRegistry
MyBeanDefinitionRegistryPostProcessor----postProcessBeanFactory
MyBeanFactoryPostProcessor....invoke
com.lin.springL.pojo.Lin@166fa74d
可以看到MyBeanDefinitionRegistryPostProcessor先于MyBeanFactoryPostProcessor执行。
BeanFactory就是根据BeanDefinitionRegistry所定义的BeanDefinition来创建对应的Bean实例。因此在此可以通过registry.registerBeanDefinition("lin", rootBeanDefinition);
来注册自定义的Bean定义,之后就会被BeanFactory初始化。
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
ApplicationListener
监听容器中发布的事件,完成事件驱动模型的开发。
例子
编写MyApplicationListener类如下:
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件:" + event);
}
}
编写MainTest类代码如下:
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConfigure.class);
applicationContext.close();
}
}
运行得到如下输出:
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:02:43 CST 2020]; root of context hierarchy]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:02:43 CST 2020]; root of context hierarchy]
可以看到容器的启动和关闭事件都被监听到了,因此可以监听ApplicationEvent及其子类的事件,所以如果需要自定义事件,继承ApplicationEvent后由Spring发布消息,然后就可以在ApplicationListener进行监听操作了。
自定义发布事件
更改MainTest代码如下:
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConfigure.class);
applicationContext.publishEvent(new ApplicationEvent(new String("自定义事件")) {
});
applicationContext.close();
}
}
执行得到输出:
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:10:32 CST 2020]; root of context hierarchy]
收到事件:com.lin.springL.MainTest$1[source=自定义事件]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:10:32 CST 2020]; root of context hierarchy]
我们发布的消息也成功被监听到。
@Override
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);
}
}
}
@EventListener
上面实现监听需要自己定义类实现ApplicationListener,在这里可以使用注解的方式,让任意一个方法成为监听方法。
例子
编写UserService类如下:
@Service
public class UserService {
//监听ApplicationEvent事件
@EventListener(classes = {ApplicationEvent.class})
public void listener(ApplicationEvent event) {
System.out.println("UserService监听事件:" + event);
}
}
编写配置类如下:
//配置类==配置文件
@Configuration
//开启自动包扫描,传入要扫描的包路径
@ComponentScan(basePackages = "com.lin.springL")
public class MainConfigure {
}
编写MainTest类如下:
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConfigure.class);
applicationContext.publishEvent(new ApplicationEvent(new String("自定义事件")) {
});
applicationContext.close();
}
}
运行得到输出:
UserService监听事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:51:57 CST 2020]; root of context hierarchy]
UserService监听事件:com.lin.springL.MainTest$1[source=自定义事件]
UserService监听事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c: startup date [Wed May 20 10:51:57 CST 2020]; root of context hierarchy]
可以看到也是可以监听到事件。