BeanPostProcessor是bean的后置处理器,BeanFactoryPostProcessor是beanFactory的后置处理器:在beanFactory标准初始化之后调用,所有的bean定义已经保存到beanFactory,但是bean的实例还没有创建。
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;
}
1、配置类
public class Blue {
public Blue (){
System.out.println("Construct.......");
}
}
@ComponentScan("ext")
@Configuration
public class Extconfig {
@Bean
public Blue blue(){
return new Blue();
}
}
2、自定义BeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor.....");
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
System.out.println("容器中bean的数量" + beanDefinitionCount);
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
Arrays.asList(beanDefinitionNames).forEach(s -> System.out.println(s));
}
}
3、测试类
public class ExtTest {
@Test
public void test1() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
}
}
4、结果
MyBeanFactoryPostProcessor.....
容器中bean的数量9
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
九月 24, 2019 4:56:42 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Disconnected from the target VM, address: '127.0.0.1:52872', transport: 'socket'
Process finished with exit code 0
5、原理
// Invoke factory processors registered as beans in the context.
//在bean初始化之前进行执行
invokeBeanFactoryPostProcessors(beanFactory);
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//执行剩余processor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
执行时机:在所有的bean定义信息将要被加载,bean实例还未出创建,优先于BeanFactoryPostProcessor执行,可以利用它给容器中额外的添加一些组件
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;
}
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* registry是bean的定义信息的保存中心,以后beanFactory就是按照BeanDefinitionRegistry里
* 保存的每一个bean定义信息创建bean创建bean实例
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("容器中bean的数量1:" + registry.getBeanDefinitionCount());
//第一种方式
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
//第二种方式
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("容器中bean的数量2:"+ beanFactory.getBeanDefinitionCount());
}
}
容器中bean的数量1:10
容器中bean的数量2:11
MyBeanFactoryPostProcessor.....
容器中bean的数量11
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
myBeanDefinitionRegistryPostProcessor
myBeanFactoryPostProcessor
blue
hello
九月 24, 2019 9:34:07 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Construct.......
Process finished with exit code 0
原理
1、IOC容器创建
2、refresh()
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
1)依次触发postProcessBeanDefinitionRegistry()方法
2)再依次触发postProcessBeanFactory()方法
4、从容器中获取到所有的BeanFactoryPostProcessor组件
依次触发postProcessBeanFactory()方法
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
监听ApplicationListener及其下面的子事件
public class ExtTest {
@Test
public void test1() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
applicationContext.close();
}
}
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("监听到事件"+event);
}
}
容器中bean的数量1:11
容器中bean的数量2:12
MyBeanFactoryPostProcessor.....
容器中bean的数量12
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
myApplicationListener
myBeanDefinitionRegistryPostProcessor
myBeanFactoryPostProcessor
blue
hello
九月 24, 2019 9:53:23 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Construct.......
监听到事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy]
九月 24, 2019 9:53:23 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy
监听到事件org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy]
步骤:
1、写一个监听器来监听某个事件,这个事件必须是ApplicationEvent的子类
2、将监听器放入容器中
3、只要容器中有相关事件的发布,我们就能监听到这个事件
ContextRefreshedEvent:容器刷新完成,所有bean都完全创建完成
ContextClosedEvent:容器关闭事件
4、发布一个事件
@Test
public void test1() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
applicationContext.close();
}
1、端点运行
2、容器对象创建,refresh();
3、容器刷新完成会发布ContextRefreshedEvent
// Last step: publish corresponding event.
finishRefresh();
4、发布事件
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
5、获取事件的多播器(派发器)
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
6、拿到所有的ApplicationLinstner
@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 :支持异步派发
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
//同步的方式执行onApplicationEvent()方法
invokeListener(listener, event);
}
}
}
7、自己发布的事件是执行一样的流程
8、容器关闭会自动发布关闭事件
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
事件的多播器是怎样拿到的
1、初始化多播器方法
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//在bean初始化之前进行执行
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//bean初始化前后进行
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.
//加载剩余的单实例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//发布事件
finishRefresh();
2、先看容器中有没有这个组件,没有的话注册一个,并加入到容器中,就可以在其他组件要派发事件的时候自动注入这个ApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
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);
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 + "]");
}
}
}
3、容器中有哪些监听器
将所有ApplicationListener类型的组件加入到派发器中
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
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);
}
}
}
3、可以自定义派发器件、传入AsyncTaskExecutor或SyncTaskExecutor支持异步或者同步
使用普通的组件也能监听到事件
@Service
public class UserService {
@EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService监听到的事件"+ event);
}
}
原理:
* @author Stephane Nicoll
* @since 4.2
* @see EventListenerMethodProcessor
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
.....
}
由此可见这个注解是在EventListenerMethodProcessor这个后置处理器来处理方法上的EventListener注解
class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware
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.
* NOTE: 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();
}
在EventListenerMethodProcessor对该方法的实现处打断点
refresh();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有的单实例bean
beanFactory.preInstantiateSingletons();
}
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("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<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
//实例化bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}