ImportBeanDefinitionRegistrar的使用

一句话概括:

  • 该接口给开发者提供了一种给bean工厂增加bd的方式.

为什么会有这种需求? 考虑某些类,我们只能获取到jar包,且想把这些类的实例交由spring管理.首先,我们无法通过在类上加@Component注解这种方式来实现;其次,可以用@Bean这种方式实现需求. 但是ImportBeanDefinitionRegistrar接口提供了更多的灵活性.其实看看这个接口的定义就能知道了.

aop and spring

aop是一种编程思想.springaspectj是这种思想的2种具体实现.

可以通过注解开启springaop功能(@EnableAspectJAutoProxy).

springaop实现,有2种形式,一种是通过运行期的动态代理实现,另外一种是委托给aspectj进行处理.

aspectj又有2种形式的实现,一种是编译期间的织入,一种是通过特殊的类加载器进行加载时的织入,即所说的ltw.spring中可以通过注解(@EnableLoadTimeWeaving)启用ltw.不过需要做一些配置:

  1. 引入spring-instrument作为新的类加载器,这个类加载器可以在加载类的时候把代理织入进去;
  2. 设置启动参数:-javaagent:C:\Users\Administrator\.m2\repository\org\springframework\spring-instrument\5.2.3.RELEASE\spring-instrument-5.2.3.RELEASE.jar.

具体功能是如何在spring中工作的,未完待续.

componentScan注解

Configures component scanning directives for use with @{@link Configuration} classes.

在使用Configuration注解时,可以同时使用这个指令配置组件扫描.作用跟xml文件里的<context:component-scan>}是一样的.

实践: demo.

spring中是如何实现的?

AbstractApplicationContextinvokeBeanFactoryPostProcessors开始.

未完待续.

spring中事件逻辑简读

简单写一下spring中事件的实现.

框架启动时,会把被listen注解的方法收集起来.当发布者publisher把事件发布委托给ApplicationEventPublisher,这个bean其实在spring中已经提前创建好了.

其实提前创建的这个bean,是AbstractApplicationContext子类,这个类中实现了publishEvent方法,而该方法由委托给了上下文中存在的ApplicationEventMulticaster进行处理.


未完待续,后面会重新仔细分析spring中事件处理的实现.


spring中的事件

spring中事件包进行一个全面的解读.

ApplicationEvent

事件对象,spring中的事件对象继承了jdk中的事件对象.继承之后只是添加了一个时间戳字段(long型),还派生出一个接口ApplicationContextEvent,该接口也是什么都没有做.

还预定了4种事件.从上图可以看出来.具体不在细说.

ApplicationListener

//todo
该接口使用ApplicationEvent对象作为操作对象.这个接口有2个子接口.这2个子接口定义是一样的.为啥会有2个子接口,这个后面需要研究一下.

2个子接口只是增加了对所监听的事件类型的一些判断功能,比如某个监听器监听一类事件,但对这一类事件的某一种不支持.那么可以通过子接口来进行一些操作.

子接口的实现类ApplicationListenerMethodAdapter,这个类是适配类.适配什么呢?从之前对spring中例子的用法可以看出,@EventListener注解是注解在方法上的.所以适配的是,把对事件的处理,委托给这个适配器处理. 当然,这个适配器本身自己也是一个监听器.

GenericApplicationListenerAdapter这个实现类,也是适配类,通过内省声明的监听器对象来决定自己感兴趣的事件的类型.当然,这个类自身也是一个监听器.

SourceFilteringListener是一个装饰类,把监视器装饰一下,这个类可以对事件进行一些过滤处理.

可以看到,这几个类都继承了Ordered接口,显然,对一个事件的监听处理,是可以通过@Order权重进行优先级排序的.

EventListenerFactory 是工厂接口,策略模式.负责对被@EventListener注解修饰的方法产生监听器对象.前面提到的ApplicationListenerMethodAdapter,这个适配类,就是通过工厂所接收到的方法,产生对应的方法的监听器对象.

ApplicationEventMulticaster

多播,同一个事件,可能会有多个监听器对其感兴趣,这个接口负责广播这个事件.其实这个接口定义的就是对这一组监听器的crud.SimpleApplicationEventMulticaster是其最终实现类.spring启动后,使用的就是这个多播器.

在上下文refresh的时候,会调用initApplicationEventMulticaster,这个方法把SimpleApplicationEventMulticaster放到上下文中.

以上,有事件源,有事件,有监听者,都齐全了.还需要一个把@EventListener注解修饰的方法转换成listener的中介.这个中介是EventListenerMethodProcessor.他实现了一些接口,在bean生命周期的某些时机,会把bean的被修饰的方法拿出来,生成一个listener,然后放到集合中去,下次事件源发布事件的时候,就可以处理事件了.从这点可以看出来,被@EventListener修饰的方法所在的类,必须是个bean.

EventPublicationInterceptor拦截器会把事件发布到ApplicationEventPublisher内注册的所有的Listener.

spring中事件的简单应用

spring中的事件也是根据jdk中的事件发展而来的.

  1. 定义事件.
  2. 定义发布者publisher,发布者也是事件源,会被事件所持有,同时,会发布事件到事件的监听者.
  3. 定义事件监听者,事件监听者负责处理事件.

1.

spring中,定义一个事件,只需要继承ApplicationEvent类即可.

2. 发布者

定义一个发布者,可以把发布者定义为一个bean,同时,把发布任务委托给spring框架中自带的bean:ApplicationEventPublisher实例.在发布者中生产事件和发布事件(即通知监听者).

3. 监听者(Listener)

5.x版本的spring中,只需要在一个public方法上加上@EventListener注解即可,当然事件跟监听者是一对多的关系,所以可以定义多个监听者,此时
可以用@Order进行有序监听.

Jdk中的事件处理

Spring源码时,发现Spring的事件处理用到了jdk中的事件处理机制.

回顾一下:

事件类EventObject: 该类其实就是把事件源(source)给包含进去了,类似于Spring中的Aware接口.在用的时候直接继承该类即可;

监听器EventListener: 是一个空接口;

示例DemoGitHub;