BeanFactory(DefaultListableBeanFactory)

image.png

ApplicationContext和BeanFactory的关系

ApplicationContext包含有BeanFactory。
可以看做BeanFactory的代理,为了代理BeanFactory的方法,实现了BeanFactory接口。具体实现调用ApplicationContext中的BeanFactory属性(DefaultListableBeanFactory)。

GenericApplicationContext AbstractRefreshableApplicationContext 都通过组合 DefaultListableBeanFactory 来实现 bean 容器的功能,区别是当多次 refresh 时, AbstractRefreshableApplicationContext 的 refreshBeanFactory 方法 (refresh 方法会调用到) 会重建 DefaultListableBeanFactory, 而 GenericApplicationContext 会报错。

Spring - 图2

  1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
  2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:
    1. 国际化支持 MessageSource
    2. 资源访问:ResourceLoader
    3. 事件传递,所有扩展了ApplicationListener的Bean都将会接受到这个事件【能发送事件applicationContext.publishEvent()】
    4. 对web的支持,可以使用contextLoader来加载容器。

Spring - 图3

【动态代理】AspectJ(Load-time weaving) & AOP & CGLIB 关系

AspectJ:两种切入方式,

  • 编译期
  • 加载期Load-time weaving

spring aop 属于 运行期,方法有

  1. jdk动态代理(InvocationHandler
  2. cglib(MethodInterceptor

aop和AspectJ的关系:spring中使用了AspectJ的注解(AspectJ 主要被 Spring 用于解析其 Pointcut 表达式

  • JDK动态代理是继承接口
    • public final class $Proxy0 extends Proxy implements Hello
    • 有接口才能将object转为目标类型
    • 1.8的时候JDK的效率已高于cglib
  • cglib是实现子类(操作字节码)
    • 不能代理final方法
    • jdk是直接写class字节码,cglib使用asm框架写字节码
  • AspectJ是静态代理,需要aspect编译器,只不过spring中使用了AspectJ的注解

    事件

  • 一个listener报错,后续listener将不会继续执行。

    收不到ApplicationEnvironmentPreparedEvent事件?

    image.png
    所以妄图通过Bean来监听ApplicationEnvironmentPreparedEvent是不行的。
    监听ApplicationEnvironmentPreparedEvent事件方法

  1. new Listener(),将listener设置到SpringApplication中。
  2. 在spring.factories中添加listener

@RunWith @SpringBootTest

SpringBoot Test及注解详解 - codedot - 博客园

@PropertySource

是ConfigurationClassPostProcessor中解析的,所以必须早于普通bean注册。
所以,要配合@Configuration使用。