Spring源码学习--06(打通Refresh方法的全链路)

目录

1.后置处理器PostProcessor

2.Aware及其子接口

 3.事件监听器模式 

4.Spring容器 的刷新逻辑


1.后置处理器PostProcessor

    后置处理器有三种

      BeanDefinitionRegistryPostProcessor: BeanDefinitionRegistry的后置处理器

      BeanFactoryPostProcessor :Bean 工厂后置处理器

      BeanPostProcessor :Bean 后置处理器

  前两个是容器级别的后置处理器,最后一个属于Bean级别的后置处理器。BeanDefinitionRegistryPostProcessor在 Bean 实例化和BeanFactoryPostProcessor 检测开始之前,注册更多的BeanDefinition,除此之外,你还可以修改已注册的 BeanDefinition 信息。在注解的方式启动容器的时候,不管是从参数里面传进来的BeanDefinitionRegistryPostProcessor还是从容器里面获取到已经注册的BeanDefinitionRegistryPostProcessor,都会先于BeanFactoryPostProcessor去执行。用途呢可以在里面去搜索某些第三方的项目里面的Class,然后通过这种方式注入进容器,就可以在容器里面去使用他们了。

@Configuration
public class WXBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		Class<User> userClass = User.class;
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(userClass);
		GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinitionBuilder.getRawBeanDefinition();
		registry.registerBeanDefinition("user", genericBeanDefinition);
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

	}
}

BeanPostProcessor 是 Bean 后置处理器接口,里面包含两个方法:postProcessBeforeInitialization 和 postProcessAfterInitialization。前者在 Bean 实例化(不是BeanDefination实例化)前调用,后者则是在实例化后。比如生成一个 Bean 的代理类,就是其子类做的。

2.Aware及其子接口

 容器对bean的逻辑本身是无侵入的,因此Bean一般不需要了解容器的状态,但是在某些情况下在bean中需要对容器进行直接的操作。这个时候就需要在bean中设定对容器的感知,这便是Aware接口的作用。

Aware是一个空的接口,能发挥作用的是它的一些实现

例如ApplicationContextAware,在容器创建这个bean的时候将容器本身作为参数传入,获取容器相关的信息

 BeanFactoryAware,在容器创建这个bean的时候将BeanFactory本身作为参数传入,获取BeanFactory相关的信息

 使用他就是直接实现他的接口即可

 3.事件监听器模式 

    什么是回调函数?简单来说就是调用一个组件的时候,按照组件的定义注册一个我们自己的方法,期待组件在特定的场景下去调用我们注册的方法。

  事件源(Evnet Source)

  事件监听器(Event Listener)事件监听器需要注册到事件源里面

  事件对象(Event Object) 作为事件源与监听器之间得消息传递

Spring里面的事件驱动模型之容器事件

1.事件ApplicationEvent

 ContextStoppedEvent:容器停止后出发的事件

 ContextRefreshedEvent:容器初始化或者刷新完成后出发的事件

 ContextClosedEvent:容器关闭后触发的事件

 ContextStartedEvent:容器启动后触发的事件

在Spring4.2之前所有的事件都必须强制继承自ApplicationEvent,在4.2以后Spring提供了一个PayloadApplicationEvent的包装类,就不再强制事件必须继承自ApplicationEvent

 

2.事件监听器ApplicationListener

 SmartApplicationListener可以对监听器进行排序

想要实现事件监听器就需要实现ApplicationListener,或者使用@EventListener,就可以将这个Bean晋升为监听器,使用sayHello方法进行监听,返回值是任意的,如果返回值不是Void,此时的返回值会被当做一个新的事件再次进行发布。

 

3.事件发布器ApplicationEventPublisher和ApplicationEventMulticaster

  ApplicationContext继承了ApplicationEventPublisher,说明ApplicationContext具有事件发布的能力,同时还存在与ApplicationEventPublisher相关的Aware接口ApplicationEventPublisherAware

 这个Aware接口上面说过是让Bean可以感知到容器的存在,我们可以在Bean里面通过Aware来获取到ApplicationEventPublisher这个实例(ApplicationContext),然后就可以向容器里面发布自定义的事件,给容器里面注册的自定义的EvnetListener去处理。

ApplicationEventMulticaster:不仅仅具有发布事件的能理,还有添加和删除事件的方法。

 SimpleApplicationEventMulticaster里面如果设置了Executor,就支持多线程去发布事件

为什么有两个事件发布的接口?为什么不使用SimpleApplicationEventMulticaster来替换掉ApplicationEventPublisher?

因为想Bean和容器他们就只想发布事件,并不想维护事件,所以Spring对事件源进行了进一步的切割

4.Spring容器 的刷新逻辑

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// 刷新容器前的准备工作
			prepareRefresh();
			// 对于XML来讲特别重要,涉及到BeanDefinition的注册,对于注册来讲仅仅是调用了子类的refreshBeanFactory
			//获取到DefaultListableBeanFactory的实例
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 为容器注册必要的系统级别的Bean,例如classLoader beanFactoryPostProcessor
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//允许容器的子类去注册postProcessor
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				//执行容器级别的后置处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//向容器注册Bean级别的后置处理器
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				//初始化国际化配置
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化事件发布者组件
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 单例Bean初始化之前,预留给子类初始化预留给子类初始化其他特殊bean的口子
				onRefresh();

				// Check for listener beans and register them.
				//向前面时间发布者组件注册监听器
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//设置一些系统级别的服务,实例化所有非懒加载的单例
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//触发初始化完成的回调方法,并发布容器刷新完成的事件给监听者
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				//重置Spring中的内核共用缓存
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空恋旅人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值