Spring 杂记
9.1 Spring框架设计
9.2 AOP 详解
9.3 Bean 核心原理
9.4 XML 配置原理
10.1 Spring Boot 核心原理
10.2 ORM-Hibernate/MyBatis
10.3 Spring 集成 ORM/JPA
容器接口与实现
BeanFactory
Spring 的核心容器,实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供。
|
|
将常用后处理器添加到beanFactory
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
- beanFactory 后处理器
org.springframework.context.annotation.internalConfigurationAnnotationProcessor:解析@Configuration、@Bean
- ConfigurationClassPostProcessor.class 可以解析 @ComponentScan @Bean @Import @ImportResource
- MapperScannnerConfigurer.class 可以解析 @MapperScanner
|
|
- bean 后处理器
org.springframework.context.annotation.internalAutowiredAnnotationProcessor:在依赖注入阶段,解析@Autowired
- 如果是 GenericApplicationContext,还需要 context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()) 才能解析 @Value
org.springframework.context.annotation.internalCommonAnnotationProcessor:解析@Resource(依赖注入阶段)、@PostConstruct(实例化后,即初始化前)、@PreDestroy(销毁前)
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
- 另外,ConfigurationPropertiesBindingPostProcessor 用于解析 @ConfigurationProperties
单例对象默认在使用时才初始化,若要预先初始化单例对象:
beanFactory.preInstantiateSingletons();
综上,beanFactory不会主动做以下事情:
不会主动调用 BeanFactory 后处理器
不会主动添加 Bean 后处理器
不会主动初始化单例
不会解析 beanFactory、
${}
、#{}注:beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders) 是 ${} 的解析器
Q:同时添加 @Autowired 和@Resource注解?
Autowired默认按照类型匹配(通过beanFactory.doResolveDependency(…)方法),
有相同类型时再按照名称匹配,Resource默认按照名称匹配。
internalAutowiredAnnotationProcessor默认优先级更高,所以Autowired生效,可以通过比较器来改变优先级(order越小优先级越高)。
ApplicationContext
继承了 BeanFactory,进行了扩展。
- MessageSource:国际化
- ResourcePatternResolver:资源通配符
- ApplicationEventPublisher:事件发布器(用于解耦)
- EnvironmentCapable:环境变量、配置信息
DispatcherServlet 称为前控制器,所有请求都先通过它。
Aware 接口
是 spring 的内置功能
bean初始化优先级:
- @PostConstruct
- Aware
- implements InitializingBean 重写方法
- @Bean(initMethod = “”)
bean销毁优先级:
- @PreDestroy
- Aware
- implements DisposableBean 重写方法
- @Bean(destroyMethod = “”)
Scope
singleton 单例:Q:单例中注入多例,多例都是同一个对象,需要推迟其他 scope bean 的获取(2种代理,2种非代理)
- 在注入目标前面加 @Lazy 生成代理对象(推荐)
- 在被注入类上添加 @Scope(value=“prototype”,proxyMode = ScopedProxyMode.TARGET_CLASS) 生成代理对象
- 声明 ObjectFactory<>,通过getObject() 来实现
- 注入 ApplicationContext,通过 context.getBean(Xxx.class)
prototype 原型
request 请求
session 会话:不同浏览器,不同会话
application 应用程序
Q:jdk>=9时,反射调用 jdk 中方法报 IllegalAccessException?
A1:重写toString()方法,不让它调用 jdk 中的方法
A2:添加参数–add-opens java.base/java.lang=ALL-UNNAMED