Spring注解驱动开发拓展

Updated on with 0 views and 0 comments

BeanFactoryPostProcessor

BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后调用,所有的Bean定义已经保存加载到BeanFactory,但是Bean的实例还未创建

执行时机:
(1)IOC创建容器对象
(2)invokeBeanFactoryPostProcessors(beanFactory) -- 执行BeanFactoryProcessor

如何找到所有的BeanFactoryProcessor?

  • 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
  • 在初始化创建其他组件之前执行
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        int beanDefinitionCount = configurableListableBeanFactory.getBeanDefinitionCount();
        String[] beanDefinitionNames = configurableListableBeanFactory.getBeanDefinitionNames();
        System.out.println("当前BeanFactory中有"+beanDefinitionCount+"个Bean,名字为"+ Arrays.toString(beanDefinitionNames));
    }
}

BeanDefinitionRegistryPostProcessor(extends BeanFactoryPostProcessor)

postProcessBeanDefinitionRegistry

在所有Bean定义信息将要被加载,但Bean还未创建之前执行,优先于BeanFactoryPostProcessor执行,可以利用它给容器中再额外添加一些组件

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        //beanDefinitionRegistry:Bean定义信息的存储中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个Bean的定义信息创建Bean实例
        System.out.println("postProcessBeanDefinitionRegistry...Bean的数量为:"+beanDefinitionRegistry.getBeanDefinitionCount());

    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor...Bean的数量为:"+configurableListableBeanFactory.getBeanDefinitionCount());

    }
}

ApplicationListener

监听容器总发布的事件,完成事件驱动开发

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);

}

步骤:

  1. 写一个监听器来监听某个事件(ApplicationEvent及其子事件),并加入到容器中
  2. 只要容器中有相关的事件发布,就能监听到这个事件
  3. 发布事件 -- applicationContext.publishEvent

事件发布流程

(1)获取事件的多播器(派发器):getApplicationEventMulticaster()
(2)multicastEven派发事件
(3)获取到所有的ApplicationListener

  • 如果有Executor,可以支持使用Executor进行异步派发
  • 否则,同步的方式执行Listerner方法,invokeListener(listener,event) -- 拿到listener回调onApplicationEvent方法
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);

        //发布事件
        applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
        });

        applicationContext.close();
@EventListener

让普通的业务逻辑组件也能监听事件

@EventListener(classes = ApplicationEvent.class)
    public void listen(ApplicationEvent event) {

    }

使用EventListenerMethodProcessor处理器来解析方法上的@EventListener

Spring容器的创建

BeanFactory的创建和预准备工作

1.prepareRefresh()刷新前的预处理

(1)initPropertySources():初始化一些属性设置,子类自定义个性化的属性设置方法
(2)getEnvironment().validateRequiredProperties():检验属性的合法等
(3)earlyApplicationEvents = new LinkedHashSet< ApplicationEvent>():保存容器中一些早期的事件

2.obtainFreshBeanFactory():获取BeanFactory

(1)refreshBeanFactory():刷新BeanFactory

  • 创建了一个this.beanFactory = new DefaultListableBeanFactory()
  • 设置ID

(2)getBeanFactory():返回刚才GenericApplicationContext创建的BeanFactory对象

(3)将创建的BeanFactory(DefaultListableBeanFactory)返回

3.prepareBeanFactory(beanFactory):BeanFactory的与准备工作(对BeanFactory进行一些设置)

(1)设置BeanFactory的类加载器、支持表达式解析器

(2)添加部分BeanPostProcessor -- ApplicationContextAwareProcessor、、

(3)设置忽略自动装配接口 -- EnvironmentAware、EmbeddedValueResolverAware、、

(4)注册可以解析的自动装配,可以直接在任何组件自动注入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext

(5)添加BEANPostProcessor -- ApplicationListenerDetector

(6)添加编译时的编译时的AspectJ

(7)给BeanFactory注册一些能用的组件:environment -- ConfigurableEnvironment)、systemProperties、systemEnvironment

4.postProcessBeanFactory(beanFactory):BeanFactory准备完成的后置处理工作

(1)子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

5.invokeBeanFactoryPostProcessor(beanFactory):执行BeanFactoryPostProcessor的方法

BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行

有两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

(1)执行BeanFactoryPostProcessor的方法

先执行BeanDefinitionRegistryPostProcessor的方法

  • 获取所有的BeanDefinitionRegistryPostProcessor
  • 先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor
  • 再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
  • 最后执行没有实现任何优先级或者顺序接口的BeanDefinitionRegistryPostProcessor

后执行BeanFactoryPostProcessor的方法

  • 获取所有的BeanFactoryPostProcessor
  • 先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor
  • 再执行实现了Ordered顺序接口的BeanFactoryPostProcessor
  • 最后执行没有实现任何优先级或者顺序接口的BeanFactoryPostProcessor

6.registerBeanPostProcessors(beanFactory):注册BeanPostProcessor(Bean的后置处理器) -- Register bean processors that intercept bean creation

不同接口类型的BeanPostProcessor在Bean创建前后的执行时机是不一样的

BeanPostProcessor

DestructionAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor

MergedBeanDefinitionPostProcessor

(1)获取所有的BeanPostProcessor,后置处理器默认都可以通过PriorityOrdered、Ordered指定优先级

(2)先注册PriorityOrdered优先级接口的BeanPostProcessor(添加到容器中)

(3)再注册实现Ordered接口的

(4)最后注册没有实现优先级接口的

(5)最终注册MergedBeanDefinitionPostProcessor

(6)之后还注册了一个ApplicationListenerDetector:在Bean创建完成后检查是否是ApplicationListener,如果是,则放到容器中

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

7.initMessageSource() -- 初始化MessageSource组件(做国际化功能,消息绑定,消息解析)

(1)获取BeanFactory

(2)看容器中是否有ID为messageSource,类型是MessageSource的组件,如果有则赋值给messageSource属性,如果没有则自己创建一个DelegatingMessageSource -- MessageSource可以取出国际化配置文件中某个文件的key值,能按照区域信息获取

(3)把创建好的MessageSource注册到容器中,以后获取国际化配置文件时,可以自动注入MessageSource,调用getMessage()

beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);

8.initApplicationEventMulticaster()

(1)获取BeanFactory

(2)从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster

(3)如果上一步没有配置,创建一个SimpleApplicationEventMulticaster

(4)将创建好的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件自动注入即可

9.onRefresh() -- 留给子容器(子类)

(1)子类重写这个方法,在容器刷新的时候可以自定义逻辑

10.registerListeners(); -- 给容器中将所有项目里面的ApplicationListener注册进来

(1)从容器中拿到所有的ApplicationListener组件

(2)将每个监听器添加到事件派发器中

getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

(3)派发之前步骤产生的事件

11.finishBeanFactoryInitialization(beanFactory) -- 初始化所有剩下的单实例Bean

(1)beanFactory.preInstantiateSingletons() -- 初始化剩下的单实例Bean

a.获取容器中所有的Bean,依次进行初始化和创建对象

b.获取Bean的定义信息 -- RootBeanDefinition

c.Bean不是抽象的,是单例的,不是懒加载的

  • getBean(beanName)、ioc.getBean()
  • doGetBean(name, null, null, false)
  • 先获取缓存中保存的单实例Bean,如果能获取到说明这个Bean之前被创建过(所有创建的单实例Bean都会被缓存起来)
  • 缓存中获取不到,开始Bean创建对象流程
  • 标记当前Bean已经被创建
  • 获取Bean的定义信息
  • 获取当前Bean依赖的其他Bean,如果有,按照getBean()把依赖的Bean先创建出来
  • 启动单实例Bean创建流程
    • createBean(beanName, mdb, args)
    • Obeject bean = resolveBeforeInstantiation(beanName, mdbToUse)
      • 【创建Bean实例】,createBeanInstance(beanName, mdb, args),利用工厂方法或者对象的构造器创建出Bean的实例
      • applyMergedBeanDefinitionPostProcessors()
      • 【Bean属性赋值】 populateBean(beanName, mdb, instanceWrapper)
      • 【Bean的初始化】

12.finishRefresh() -- 完成BeanFactory的初始化创建工作,IOC容器创建完成

(1)initLifecycleProcessor(); 初始化和生命周期有关的后置处理器 -- LifecycleProcessor

(2)getLifecycleProcessor().onRefresh(); 拿到前面定义的生命周期处理器(BeanFactory),回调refresh()

(3)publishEvent(new ContextRefreshedEvent(this)); 发布容器刷新完成事件

(4)LiveBeansView.registerApplicationContext(this);

总结

1.Spring容器在启动的时候,先会保存所有注册进来的Bean定义信息

(1)xml注册Bean -- < bean>

(2)注解注册Bean

2.Spring容器会在合适的时机创建这些Bean

(1)用到这个Bean的时候,利用getBean()创建Bean,创建完成后保存在容器中

(2)统一创建剩下的所有Bean

3.后置处理器

(1)每个Bean创建完成,都会使用各种后置处理器来增强Bean的功能

4.事件驱动模型

ApplicationListener -- 事件监听