BeanFactory(DefaultListableBeanFactory)
ApplicationContext和BeanFactory的关系
ApplicationContext包含有BeanFactory。
可以看做BeanFactory的代理,为了代理BeanFactory的方法,实现了BeanFactory接口。具体实现调用ApplicationContext中的BeanFactory属性(DefaultListableBeanFactory)。
GenericApplicationContext 和 AbstractRefreshableApplicationContext 都通过组合 DefaultListableBeanFactory 来实现 bean 容器的功能,区别是当多次 refresh 时, AbstractRefreshableApplicationContext 的 refreshBeanFactory 方法 (refresh 方法会调用到) 会重建 DefaultListableBeanFactory, 而 GenericApplicationContext 会报错。
- BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
- ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:
1. 国际化支持 MessageSource
2. 资源访问:ResourceLoader
3. 事件传递,所有扩展了ApplicationListener的Bean都将会接受到这个事件【能发送事件applicationContext.publishEvent()】
4. 对web的支持,可以使用contextLoader来加载容器。
【动态代理】AspectJ(Load-time weaving) & AOP & CGLIB 关系
AspectJ:两种切入方式,
- 编译期
- 加载期Load-time weaving
spring aop 属于 运行期,方法有
- jdk动态代理(InvocationHandler)
- 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事件?
所以妄图通过Bean来监听ApplicationEnvironmentPreparedEvent是不行的。
监听ApplicationEnvironmentPreparedEvent事件方法
- new Listener(),将listener设置到SpringApplication中。
- 在spring.factories中添加listener
@RunWith @SpringBootTest
SpringBoot Test及注解详解 - codedot - 博客园
@PropertySource
是ConfigurationClassPostProcessor中解析的,所以必须早于普通bean注册。
所以,要配合@Configuration使用。