BeanFactoryPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
|
与BeanPostProcessor进行比较
-
BeanPostProcessor
bean后置处理器,bean创建对象初始化前后进行拦截工作的
-
BeanFactoryPostProcessor
beanFactory的后置处理器;在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
标准初始化?所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
通俗点说beanFactoryPostProcessor的作用就是在BeanDefinition定义好后可以有个二次修改的机会
演示:
自定义bean实现BeanFactoryPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
|
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
|
源码分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
@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);
// 会在此处执行BeanFactoryPostProcessor逻辑,在这个点除了工厂类没有其他任何bean被实例化
// 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();
}
。。。
}
}
|
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
如何找到所有的BeanFactoryPostProcessor并执行他们的方法
- 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
- 在初始化创建其他组件前面执行
BeanDefinitionRegistryPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
|
说明:
- 在所有bean定义信息将要被加载,bean实例还未创建时调用;所以会在BeanFactoryPostProcessor之前执行
- 可以利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件
演示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.eh.ext;
import com.eh.bean.Red;
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;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:" + beanFactory.getBeanDefinitionCount());
}
//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:" + registry.getBeanDefinitionCount());
//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Red.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
|
源码分析:
1
2
3
4
5
6
7
|
1)、ioc创建对象
2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
1、依次触发所有的postProcessBeanDefinitionRegistry()方法
2、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法
|
ApplicationListener
监听容器中发布的事件;事件驱动模型开发;监听 ApplicationEvent 及其下面的子事件;
1
2
3
4
5
6
7
8
9
10
|
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
|
ApplicationListener的使用
-
写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.eh.ext;
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) {
System.out.println("收到事件:" + event);
}
}
|
-
把监听器加入到容器
-
只要容器中有相关事件的发布,我们就能监听到这个事件;
- ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
- ContextClosedEvent:关闭容器会发布这个事件;
-
发布一个事件
1
2
3
4
5
6
7
|
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件;
applicationContext.publishEvent(new ApplicationEvent("发布事件") {
});
applicationContext.close();
}
|
-
测试结果
1
2
3
|
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3891771e, started on Sat Oct 31 12:34:33 CST 2020]
收到事件:com.eh.MainTest$1[source=发布事件]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3891771e, started on Sat Oct 31 12:34:33 CST 2020]
|
原理:
以ContextRefreshedEvent为例
事件发布流程
1
2
3
4
5
6
7
8
9
10
11
|
onApplicationEvent:13, MyApplicationListener (com.eh.ext)
doInvokeListener:172, SimpleApplicationEventMulticaster (org.springframework.context.event)
invokeListener:165, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
publishEvent:404, AbstractApplicationContext (org.springframework.context.support)
publishEvent:361, AbstractApplicationContext (org.springframework.context.support)
// 容器刷新完成会发布ContextRefreshedEvent事件
finishRefresh:898, AbstractApplicationContext (org.springframework.context.support)
refresh:554, AbstractApplicationContext (org.springframework.context.support)
<init>:89, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:15, MainTest (com.eh)
|
-
publishEvent(new ContextRefreshedEvent(this));
-
获取事件的多播器(派发器):getApplicationEventMulticaster()
-
multicastEvent派发事件
-
获取到所有的ApplicationListener;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 如果有Executor,可以支持使用Executor进行异步派发;
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
// 否则,同步的方式直接执行listener方法;
// 拿到listener回调onApplicationEvent方法
invokeListener(listener, event);
}
}
}
|
事件派发器
1
2
3
4
5
|
1)、容器创建对象:refresh();
2)、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;
|
容器中有哪些监听器
1
2
3
4
5
6
|
1)、容器创建对象:refresh();
2)、registerListeners();
从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
//将listener注册到ApplicationEventMulticaster中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
|
@EventListener
事件监听除了实现ApplicationListener外还可以使用注解@EventListener进行实现
注解定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/**
...
<p>Processing of {@code @EventListener} annotations is performed via
注解处理器 EventListenerMethodProcessor
* the internal {@link EventListenerMethodProcessor} bean which gets
...
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String condition() default "";
}
|
注解使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Service
public class BookService {
@EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent event) { // 使用方法参数接受事件
System.out.println("BookService监听到的事件:" + event);
}
}
// 运行结果:
BookService监听到的事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3891771e, started on Sat Oct 31 12:59:10 CST 2020]
BookService监听到的事件:com.eh.MainTest$1[source=发布事件]
BookService监听到的事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3891771e, started on Sat Oct 31 12:59:10 CST 2020]
|
原理:
使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
1
2
|
public class EventListenerMethodProcessor
implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor {
|
EventListenerMethodProcessor实现了SmartInitializingSingleton接口的afterSingletonsInstantiated方法,
在这个方法中将使用有@EventListener注解的方法转成一个ApplicationListenerBean并且注入到容器中
1
2
3
4
5
6
|
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
}
context.addApplicationListener(applicationListener);
|
之后与MyApplicationListener一样,在调用publishEvent的时候触发回调
afterSingletonsInstantiated方法执行时机
1
2
3
4
5
|
1)、ioc容器创建对象并refresh();
2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
1)、先创建所有的单实例bean;getBean();
2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
如果是就调用afterSingletonsInstantiated();
|
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
- 先创建所有的单实例bean;getBean();
- 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 先创建所有的单实例bean;getBean();
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
// 调用如果是就调用afterSingletonsInstantiated
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
|