Spring注解开发
今天,来讲解其他的扩展原理,帮助大家学习其他的小知识点
BeanFactoryPostProcessor
BeanPostProcessor:bean的后置处理器,bean创建对象初始化前后进行拦截工作的。
BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的Bean的定义已经保存加载到BeanFactory,但是bean的实例还没有创建。
创建ExConfig配置类:
@Configuration
@ComponentScan("com.liuzhuo.ext")
public class ExtConfig {
@Bean
public Blue blue() {
return new Blue();
}
}
创建自定义的BeanFactoryPostProcessor:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* @param beanFactory
* @throws BeansException
* 在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,
* 此时,所有的bean的定义信息已经保存到BeanFactory,但是Bean还没有创建
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory·······");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
创建新的测试类:
public class IoCTest_EXT {
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.close();
}
}
运行:
postProcessBeanFactory·······
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
extConfig
myBeanFactoryPostProcessor
blue
能看到,我们获取了所有的BeanFactory中定义的bean了,但是还没有创建bean的实例对象。
调试:
给MyBeanFactoryPostProcessor中的postProcessBeanFactory方法加上断点,并运行。
过程:
1)加载容器。
2)refresh();刷新容器
3)invokeBeanFactoryPostProcessors(beanFactory);
@Override
public void refresh() throws BeansException, IllegalStateException {
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);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
}
能发现,invokeBeanFactoryPostProcessors(beanFactory);是在finishBeanFactoryInitialization(beanFactory);方法之前的,就说明了BeanFactoryPostProcessor是在bean的实例化之前的,是在BeanFactory实例化之后的。
BeanDefinitionRegisterPostProcessor
BeanDefinitionRegisterPostProcessor extends BeanFactoryPostProcessor
在所有bean定义信息将要被加载,bean实例还未创建。
优先于BeanFactoryPostProcessor执行
利用BeanDefinitionRegisterPostProcessor给容器中再额外添加一些组件。
原理:
1)ioc创建对象
2)refresh() -> invokeBeanFactoryPostProcessors(beanFactory);
3) 从容器中获取所有的BeanDefinitionRegisterPostProcessor组件。
1)依次触发所有的postProcessorBeanDefinitionRegistry()方法
2)再次触发postProcessorBeanFactory()方法的BeanFactoryPostProcessor;
4)再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessorBeanFactory()方法
创建MyBeanDefinitionRegisterPostProcessor类:
@Component
public class MyBeanDefinitionRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {
//先执行
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry······");
int count = registry.getBeanDefinitionCount();
System.out.println("容器中注册的bean的个数(1):" + count);
//还能注册新的bean组件
RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
registry.registerBeanDefinition("hello", beanDefinition);
}
//后执行
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory··········");
int count = beanFactory.getBeanDefinitionCount();
System.out.println("容器中注册的bean的个数(2):" + count);
}
}
运行测试类:
十月 22, 2018 11:32:15 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 11:32:15 CST 2018]; root of context hierarchy
postProcessBeanDefinitionRegistry······
容器中注册的bean的个数(1):10
postProcessBeanFactory··········
容器中注册的bean的个数(2):11
十月 22, 2018 11:32:15 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
postProcessBeanFactory·······
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
extConfig
myBeanDefinitionRegisterPostProcessor
myBeanFactoryPostProcessor
blue
hello
十月 22, 2018 11:32:15 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 11:32:15 CST 2018]; root of context hierarchy
Process finished with exit code 0
能发现
1)首先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
2)再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
3)最后执行BeanFactoryPostProcessor的postProcessBeanFactory()方法
调试(原理)
给MyBeanDefinitionRegisterPostProcessor的postProcessBeanDefinitionRegistry()方法打上断点,并debug。
1)加载容器
2)refresh();刷新容器
3)invokeBeanFactoryPostProcessors(beanFactory);和BeanFactoryPostProcessor的流程一样
4)invokeBeanFactoryPostProcessors()
在invokeBeanFactoryPostProcessors()方法中,可以看到
1)首先获取所有的BeanDefinitionRegistryPostProcessor的定义信息
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
2)然后调用invokeBeanDefinitionRegistryPostProcessors()方法:
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
3) 再调用invokeBeanFactoryPostProcessors:
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
4) 获取所有的BeanFactoryPostProcessor的定义信息
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
5)调用invokeBeanFactoryPostProcessors:
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
ApplicationListener:
监听容器中发布的事件。事件驱动模型开发。
步骤:
1)写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
2) 把监听器加入到容器中
3)只要容器中有相关事件的发布,我们就能监听到这个事件
4)发布一个事件: applicationContext.publishEvent();
编写一个MyApplicationListener
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("监听:" + event);
}
}
运行测试类:
十月 22, 2018 8:42:11 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
监听:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 20:42:11 CST 2018]; root of context hierarchy]
十月 22, 2018 8:42:11 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 20:42:11 CST 2018]; root of context hierarchy
监听:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 20:42:11 CST 2018]; root of context hierarchy]
说明容器,为我们发布了两个事件:ContextRefreshedEvent 和 ContextClosedEvent
发布自己的事件
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.publishEvent(new ApplicationEvent(new String("自定义事件")) {
});
applicationContext.close();
}
}
运行:
监听:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 20:47:38 CST 2018]; root of context hierarchy]
监听:com.liuzhuo.test.IoCTest_EXT$1[source=自定义事件]
监听:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Mon Oct 22 20:47:38 CST 2018]; root of context hierarchy]
原理:
1)初始化容器;refresh();
2)finishRefresh(); // Last step: publish corresponding event.
3)publishEvent(new ContextRefreshedEvent(this));发布事件
4)getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);获取派发器
5)获取所有的ApplicationListener:for (final ApplicationListener<?> listener : getApplicationListeners(event, type))
6)如果有Executor,可以支持使用Executor进行异步派发,否则,使用同步方式直接执行invokeListener(listener, event);
7)doInvokeListener(listener, event);回调listener.onApplicationEvent(event);
我们这里的三个事件:
1)finishRefresh();容器刷新完成后,执行ContextRefreshedEvent事件。
2)自己发布的事件
3)容器关闭会发布ContextClosedEvent事件
事件派发器(EventMulticaster):
1)容器创建对象;refresh();
2)initApplicationEventMulticaster();初始化事件派发器
3)先去查看容器中是否有id=“applicationEventMulticaster”组件,如果有直接使用,没有的话,new SimpleApplicationEventMulticaster()组件。并且加入到容器中。我们就可以在其他组件要派发事件时,自动注入这个applicationEventMulticaster组件。
容器中有哪些监听器:
1)容器创建对象;refresh();
2)registerListeners(); //注册监听器
从容器中拿到所有的监听器,把它们注册到applicationEventMulticaster中。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
@EventListener
@EventListener注解,可以使普通类的普通方法来监听事件,不用去实现ApplicationEvent接口。
1)在com.liuzhuo.ext包下,创建UserService类:
@Service
public class UserService {
@EventListener(value = {ApplicationEvent.class})
public void listen(ApplicationEvent event) {
System.out.println("UserService监听:" + event);
}
}
2) 运行IoCTest_EXT测试类:
UserService监听:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Tue Oct 23 09:52:08 CST 2018]; root of context hierarchy]
监听:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Tue Oct 23 09:52:08 CST 2018]; root of context hierarchy]
UserService监听:com.liuzhuo.test.IoCTest_EXT$1[source=自定义事件]
监听:com.liuzhuo.test.IoCTest_EXT$1[source=自定义事件]
UserService监听:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Tue Oct 23 09:52:08 CST 2018]; root of context hierarchy]
监听:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d1e7682: startup date [Tue Oct 23 09:52:08 CST 2018]; root of context hierarchy]
3) 原理:
@EventListener使用EventListenerMethodProcessor处理器来完成的
* @author Stephane Nicoll
* @since 4.2
* @see EventListenerMethodProcessor
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener
点击EventListenerMethodProcessor处理器:
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware
实现了SmartInitializingSingleton接口,所有重点是SmartInitializingSingleton接口。
点击SmartInitializingSingleton接口:
public interface SmartInitializingSingleton {
/**
* Invoked right at the end of the singleton pre-instantiation phase,
* with a guarantee that all regular singleton beans have been created
* already. {@link ListableBeanFactory#getBeansOfType} calls within
* this method won't trigger accidental side effects during bootstrap.
* <p><b>NOTE:</b> This callback won't be triggered for singleton beans
* lazily initialized on demand after {@link BeanFactory} bootstrap,
* and not for any other bean scope either. Carefully use it for beans
* with the intended bootstrap semantics only.
*/
void afterSingletonsInstantiated();
}
其中有一个方法:afterSingletonsInstantiated(); 该方法是在所有的单实例初始化完成后才调用的。
调试:
给UserService类打上断点,并debug。
1)ioc容器创建对象;refresh();刷新容器
2)finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean
3)先创建所有的单实例bean;getBean();
4) 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的,如果是就调用afterSingletonsInstantiated()方法