Spring启动原理和可扩展设计分析

Spring启动原理和可扩展设计分析
简述spring核心是一个容器 , 但是却能在它身上像插件一样集成很多功能 , 在设计上要做到封闭修改、扩展开放 , 这一点spring做的很优秀 , 对开发框架有很好的借鉴和指导意义 。
本文通过分析spring的启动过程来分析spring扩展开放的设计实现 , 下面主要集中在两个点来分析:Aware和BeanPostProcessor 。spring自身很多扩展功能也都是通过这两个机制来实现 。
原则spring在启动过程中会注册很多回调来实现各种扩展功能 , 回调的形式最重要的是Aware和BeanPostProcessor 。
spring各种不同业务都是一个思路:

  1. 创建不同的ApplicationContext
  2. 不同的ApplicationContext写死一个Aware类型的BeanPostProcessor
  3. 由写死的Aware类型BeanPostProcessor来加载特殊业务的各种逻辑
Aware每当spring容器完成某件事情(如ApplicationContext初始化完成)时都会通知Aware , Aware通常都具有一些setXXX()的方法 , 如BeanFactoryAware:
public interface BeanFactoryAware extends Aware { void setBeanFactory(BeanFactory beanFactory) throws BeansException;}BeanPostProcessor可以对spring扫描到的bean做手脚 , 初始化前和后
public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}Spring 启动过程spring容器启动的模板编排在org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException { 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. //子类通常在这里添加自己需要的BeanPostProcessor postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //查找所有BeanPostProcessor并注册到容器中 , bean初始化时会来调用bpp 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(); }}其中AbstractApplicationContext#prepareBeanFactory里注册ApplicationContext的Aware处理器:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))ApplicationContextAwareProcessor里会触发各种aware
  1. ApplicationContextAware
  2. ApplicationEventPublisherAware
  3. ResourceLoaderAware
  4. EmbeddedValueResolverAware
  5. EnvironmentAware
实现Aware的各种bean接收到回调后就能获取各自想要的东西(ApplicationContext、ResourceLoader等) , 有了这些东西他们就可以实现自己的个性化逻辑
spring web启动下面以spring web为例看看Spring web是如何在spring的基础上实现扩展的 。
spring web的ApplicationContext大多集成自AbstractRefreshableWebApplicationContext
首先 , 还是那个套路 , 创建特殊的ApplicationContext , 然后写死一个BeanPostProcessor
AbstractRefreshableWebApplicationContext#postProcessBeanFactory
@Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));}ServletContextAwareProcessor处理两种类型的Aware
  1. ServletContextAware
  2. ServletConfigAware
这是上面说的典型的套路
实现了ServletContextAware的bean就这样获取到了web上下文 , 可以做自己的事情了
spring web初始化方式web.xml + ContextLoaderListener
< listener > < listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class ></ listener ><context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/spring/applicationContext.xml</param-value></context-param>ContextLoaderListener 初始化WebApplicationContext 判断启动哪种WebApplicationContext


推荐阅读