1、容器接口
1.1 BeanFactory 是什么?
- 它是 ApplicationContext 的父接口
- 它是 Spring 的核心容器,主要的 ApplicationContext 实现了【组合】了它的功能
1.2 BeanFactory 能干些什么?
- 从代码看表面上只有 getBean,看下图 BeanFactory 的所有方法
- 实际上控制反转,基本的依赖注入、Bean 的生命周期的各种功能,都由它的实现类 DefaultListableBeanFactory 提供
1.3 DefaultListableBeanFactory
DefaultListableBeanFactory
是 Spring 框架中的一个核心类,用于管理和配置 Bean 实例。它是 BeanFactory
接口的默认实现,提供了完整的 Bean 工厂功能,包括 Bean 的注册、依赖注入、生命周期管理等。
主要功能
DefaultListableBeanFactory
提供了以下主要功能:
- Bean 注册:支持通过编程方式或配置文件注册 Bean 定义。
- 依赖注入:自动解析 Bean 之间的依赖关系,并完成注入。
- Bean 生命周期管理:管理 Bean 的初始化、销毁等生命周期回调。
- Bean 查找:根据名称或类型查找 Bean 实例。
ConfigurableApplicationContext context = SpringApplication.run(A01Application.class, args);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
System.out.println(beanFactory);
// 运行结果
org.springframework.beans.factory.support.DefaultListableBeanFactory@2a3591c5: defining beans ......................................
通过关系图可以看到大部分都是接口和抽象类,其中 DefaultSingletonBeanRegistry 就是存放单例对象的实现类
1.4 DefaultSingletonBeanRegistry
它是 SingletonBeanRegistry
接口的默认实现,提供了单例 Bean 的注册、获取、销毁等功能。
主要功能
DefaultSingletonBeanRegistry
提供了以下主要功能:
- 注册单例 Bean:通过
registerSingleton
方法,可以将一个单例 Bean 注册到容器中。 - 获取单例 Bean:通过
getSingleton
方法,可以根据 Bean 的名称获取已注册的单例 Bean。 - 销毁单例 Bean:通过
destroySingleton
方法,可以销毁指定的单例 Bean。 - 管理 Bean 的依赖关系:通过
registerDependentBean
和getDependentBeans
方法,可以管理 Bean 之间的依赖关系。
Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
map.entrySet().stream().forEach(e -> System.out.println(e.getKey() + " = " + e.getValue()));
1.5 ApplicationContext 有哪些扩展功能?
1.5.1 国际化
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
1.5.2 获取资源
Resource resource = context.getResource("classpath:application.yml");
System.out.println(resource);
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
Arrays.stream(resources).forEach(System.out::println);
1.5.3 获取环境变量
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
1.5.4 事件发布
import org.springframework.context.ApplicationEvent;
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(Object source) {
super(source);
}
}
// 事件发布
context.publishEvent(new UserRegisteredEvent(context));
2、容器实现
2.1 BeanFactory 实现
public class TestBeanFactory {
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
}
@Slf4j
static class Bean1 {
public Bean1() {
log.debug("构造 Bean1()");
}
@Autowired
private Bean2 bean2;
public Bean2 getBean2() {
return bean2;
}
}
@Slf4j
static class Bean2 {
public Bean2() {
log.debug("构造 Bean2()");
}
}
}
2.2 Bean 注册
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// bean 的定义 (class, scope, 初始化方法, 销毁)
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope(BeanDefinition.SCOPE_SINGLETON).getBeanDefinition();
// 注册 beanDefinition
beanFactory.registerBeanDefinition("config", beanDefinition);
// 获取 beanDefinitionName
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
// 输出结果
config
2.3 BeanFactoryPostProcessor
这里有个疑问,Config 类已经加了 @Configuration 注解,按照以往使用 Spring 时,Bean1、Bean2 都应该注册到 BeanFactory,可是输出结果只有 config,这说明 BeanFactory 缺少解析 @Configuration 注解的能力,而是由 BeanFactory 添加的后处理器来解析
// 给 BeanFactory 添加一些常用的后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
// 输出结果
config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
这里多了5个 bean,从名字就可以看出 org.springframework.context.annotation.internalConfigurationAnnotationProcessor,就是处理 @Configuration 注解的,而此时后处理器是没有工作的
我们先调用 BeanFactoryPostProcessor.postProcessBeanFactory(),来解析@Configuration
// BeanFactory 后处理器主要功能,补充了一些 bean 的定义
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values()
.forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
// 输出结果
config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
bean1
bean2
可以看到这时 bean1 和 bean2 都已注册到 BeanFactory 中
internalConfigurationAnnotationProcessor -->> ConfigurationClassPostProcessor
// 解析 @Configuration、@Bean 等配置类注解
internalAutowiredAnnotationProcessor -->> AutowiredAnnotationBeanPostProcessor
// 解析 @Autowired 注解
internalCommonAnnotationProcessor -->> CommonAnnotationBeanPostProcessor
// 解析 @Resource 注解
internalEventListenerProcessor -->> EventListenerMethodProcessor
// 解析 @EventListener 注解
internalEventListenerFactory -->>DefaultEventListenerFactory
// 用于 创建事件监听器实例, 在 EventListenerMethodProcessor.processBean()调用了
获取 bean
Bean1 bean1 = beanFactory.getBean(Bean1.class);
System.out.println("获取bean2 >>" + bean1.getBean2());
// 输出结果
15:07:59.137 [main] DEBUG com.example.spring.a02.TestBeanFactory$Bean1 - 构造 Bean1()
获取bean2 >> null
2.4 BeanPostProcessor
日志发现 Bean1 实例化了,但是并没有注入 Bean2,也没有对 Bean2 实例化,这是因为 @Autowired和 @Resource 是由 BeanPostProcessor 处理的,也就是 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor
// Bean 后处理器,针对 bean 的生命周期的各个阶段提供扩展,例如 @Autowired @Resource
beanFactory.getBeansOfType(BeanPostProcessor.class).values()
.forEach(beanFactory::addBeanPostProcessor);
Bean1 bean1 = beanFactory.getBean(Bean1.class);
System.out.println("获取bean2 >> " + bean1.getBean2());;
// 输出结果
15:52:36.665 [main] DEBUG com.example.spring.a02.TestBeanFactory$Bean1 - 构造 Bean1()
15:52:36.671 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
15:52:36.671 [main] DEBUG com.example.spring.a02.TestBeanFactory$Bean2 - 构造 Bean2()
获取bean2 >> com.example.spring.a02.TestBeanFactory$Bean2@4461c7e3
2.5 主动实例化单例 Bean
这里又会发现,Bean 的实例化在 getBean 时才创建,并不是 BeanFactory 注册时创建的,形成了懒加载的现象,这是因为需要调用 beanFactory.preInstantiateSingletons() 提前实例化单例,如果加上了 @Lazy 注解的 bean 就不会实例化了
// 提前实例化 bean,如果比调用此方法,bean只有在首次调用 beanFactory.getBean() 才会实例化,除了有 @Lazy 的bean
beanFactory.preInstantiateSingletons();
但是如果在 bean1 加上了 @Lazy 注解,就会发现只实例化了 bean2
如果在 bean2 加上 @Lazy 注解,按理说 bean2 不会实例化,可是日志中却显示实例化了 bean2
哇哦!!!这是什么道理呢,刚才说了 beanFactory.preInstantiateSingletons() 不会实例化加上 @Lazy 注解的 bean ???
仔细用脚趾头想一下就明白了,这是因为在 Bean1 中需要注入 Bean2,所以就需要一起把 Bean2 实例化了呀
那不想 bean2 提前实例化,需要在注入 bean2 的地方也加上 @Lazy 注解
小总结:
BeanFactory 不会做的事情
- 不会主动调用 BeanFactory 后处理器
- 不会主动添加 Bean 后处理器
- 不会主动初始化单例
- 不会解析 beanFactory 还不会解析占位符( ${ } 与 #{ } )
2.6 扩展:BeanPostProcessor 的执行顺序
引出问题
先抛出一个不可能使用的问题:如果一个注入既加了 @Autowired 也加了 @Resouce,那是 @Autowired 先注入,还是 @Resource 先注入???
先加些代码
这里在 Bean1 注入 Inter,但是 @Autowired 是通过类型注入的,Bean3 和 Bean4 都实现了 Inter,@Autowired 不知道该注入哪个 Bean,所以运行后会报错
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bean1': Unsatisfied dependency expressed through field 'inter'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.spring.a02.TestBeanFactory$Inter' available: expected single matching bean but found 2: bean3,bean4
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
at com.example.spring.a02.TestBeanFactory.main(TestBeanFactory.java:61)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.spring.a02.TestBeanFactory$Inter' available: expected single matching bean but found 2: bean3,bean4
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1369)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
... 12 more
可以将属性名改成 bean3,因为如果Bean的类型又多个,可以通过 bean 名称匹配
那加了@Resource(name = "bean4"),就会注入 Bean4
那我们回到上方引出的问题,既加了 @Autowired 也加了 @Resouce,到底是注入 Bean3 还是Bean4 呢?答案是 Bean3
所以是问题的答案是 @Autowired 先注入
问题分析
这是因为 BeanPostProcessor 是有执行顺序的,在上方代码中我手动调用了 BeanPostProcessor,顺序是由 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory) 注册的
先改一下代码,输出一下 BeanPostProcessor 的顺序
从日志可以看到,AutowiredAnnotationBeanPostProcessor 在 CommonAnnotationBeanPostProcessor前面
那顺序可以控制吗?答案是:可以的,加入比较器进行逆序添加,输出的顺序就改变了,而且注入的 Bean也变成了 bean4
那 beanFactory.getDependencyComparator() 这个比较器从哪来的呢?
我们看一下 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
可以看到是set了 AnnotationAwareOrderComparator 比较器,实现了 Comparator 接口,
AnnotationAwareOrderComparator 的 compare 方法是继承父类 OrderComparator
我们可以看到,最终是调用了 bean 对象的 getOrder() 方法,那我们分别看一下两个类的 order
从代码可以看到,CommonAnnotationBeanPostProcessor的 Order 值更小,所所以 sorted(beanFactory.getDependencyComparator()) 进行排序后,CommonAnnotationBeanPostProcessor 排在了前面执行,所以就先注册了 bean4
Spring 内的执行顺序
首先告诉你结果,Spring 内部也是调用的 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory) 加入 BeanPostProcessor 的,但是 CommonAnnotationBeanPostProcessor 是先执行的,
那我们看一下源码
AbstractApplicationContext.refresh()
registerBeanPostProcessors(beanFactory); 很明显就是注册 BeanPostProcessor
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取 bean 后处理器名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 将实现PriorityOrdered、Ordered和其他功能的BeanPostProcessors分开。
// 实现优先级排序的后处理器
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 内部后处理器
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先注册实现优先级排序的后处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 根据 order 排序
// 注册,其实内部实现就是添加到 beanFactory 中的 Bean后处理器的列表 ( CopyOnWriteArrayList )
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 再注册实现 Orderd 接口的后处理器
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 注册,其实内部实现就是添加到 beanFactory 中的 Bean后处理器的列表 ( CopyOnWriteArrayList )
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 注册所有常规后处理器
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,重新注册所有内部后处理器
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 添加 识别并注册ApplicationListener 的后处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
来看一下排序的方法
排序之前的顺序
排序之后的顺序
我们可以看到,排序之后 CommonAnnotationBeanPostProcessor 在 AutowiredAnnotationBeanPostProcessor 之前
那 Spring 内部的执行逻辑就已经很明了了,CommonAnnotationBeanPostProcessor 先执行,所以注入的是 Bean4
2.2 ApplicationContext 实现
2.2.1 ClassPathXmlApplicationContext
2.2.2 FileSystemXmlApplicationContext
2.2.3 AnnotationConfigApplicationContext
2.2.4 AnnotationConfigServletWebServerApplicationContext
3、Bean 的生命周期
3.1 Spring Bean 生命周期各个阶段
@Component
@Slf4j
public class LifeCycleBean {
public LifeCycleBean() {
log.debug("构造 LifeCycleBean");
}
@Autowired
public void autowire(@Value("${JAVA_HOME}") String home) {
log.debug("依赖注入:{}", home);
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@PreDestroy
public void destroy() {
log.debug("销毁");
}
}
@Component
@Slf4j
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 销毁之前执行,如 @PreDestroy ");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 实例化之前执行,这里返回的对象会替换掉原本的 bean ");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 实例化之后执行,如果返回false 会跳过依赖注入阶段 ");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 依赖注入阶段执行,如 @Autowired、@Value、@Resource ");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 初始化之前执行,这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties ");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<<<<<< 初始化之后执行,这里返回的对象会替换掉原本的 bean, 如 代理增强 ");
}
return bean;
}
}
@SpringBootApplication
public class A03Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(A03Application.class, args);
context.close();
}
}
3.2 模板方法
提高扩展性
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
beanFactory.getBean();
}
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean);
for (BeanPostProcessor processor : processors) {
processor.inject(bean);
}
System.out.println("初始化 " + bean);
return bean;
}
private List<BeanPostProcessor> processors = new ArrayList<>();
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
processors.add(beanPostProcessor);
}
}
static interface BeanPostProcessor {
// 对依赖注入阶段的扩展
public void inject(Object bean);
}
}
4、Bean 后处理器
4.1 Bean 后处理器的作用
为 Bean 生命周期各个阶段提供扩展
-
AutowiredAnnotationBeanPostProcessor // 解析 @Autowired @Value
-
CommonAnnotationBeanPostProcessor // 解析 @Resource @PostConstruct @PreDestroy
-
ConfigurationPropertiesBindingPostProcessor // 解析 @ConfigurationProperties
4.2 AutowiredAnnotationBeanPostProcessor 运行分析
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取 Bean 加了 @Autowired @Value 的成员变量、方法参数信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 调用 InjectionMetadata 来进行依赖注入,注入时按类型查找值
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
public class InjectionMetadata {
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历获取到的要注入的元素
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
}
InjectedElement有两个实现类
-
AutowiredFieldElement // 通过属性注入
-
AutowiredMethodElement // 通过方法注入
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 解析属性值
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
// 通过反射set属性值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
// 将属性封装成即将将注入的特定依赖项的描述符。包装构造函数参数、方法参数或字段,允许统一访问其元数据
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 获取类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
// beanFactory 解析依赖,获取需要的注入值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
}
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 这里做解析依赖
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
}
由于源码太多,这里就不继续深扒了,我们知道了最后是调用 DefaultListableBeanFactory.doResolveDependency 获取注入值
我们将代码简化处理,逻辑就简单清晰了,
// 按属性名注入
Field bean3Field = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor dd1 = new DependencyDescriptor(bean3Field, true);
Object bea3 = beanFactory.doResolveDependency(dd1, null, null, null);
System.out.println(bea3);
ReflectionUtils.makeAccessible(bean3Field);
bean3Field.set(bean1, bea3);
// 按方法注入
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), true);
Object bean2 = beanFactory.doResolveDependency(dd2, null, null, null);
ReflectionUtils.makeAccessible(setBean2);
setBean2.invoke(bean1, bean2);
// @Value注入
Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome, 0), true);
Object home = beanFactory.doResolveDependency(dd3, null, null, null);
ReflectionUtils.makeAccessible(setHome);
setHome.invoke(bean1, home);
5、BeanFactory 后处理器
5.1 BeanFactory 后处理器的作用
为BeanFactory 提供扩展
5.2 常见的 BeanFactory 后处理器
BeanFactoryPostProcessor | 作用 |
---|---|
ConfigurationClassPostProcessor | 解析 @ComponentScan @Bean @Import @ImportResource |
MapperScannerConfigurer | @MapperScanner mybatis扫描 mapper |
5.3 ConfigurationClassPostProcessor 源码解析
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor ,而BeanDefinitionRegistryPostProcessor 继承了BeanFactoryPostProcessor ,按照之前分析过的容器刷新流程,ConfigurationClassPostProcessor 会先执行postProcessBeanDefinitionRegistry,再处理postProcessBeanFactory方法
。
5.3.1 postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor先执行postProcessBeanDefinitionRegistry:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
// throw ...
}
if (this.factoriesPostProcessed.contains(registryId)) {
// throw new ...
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
重点在最后一行 processConfigBeanDefinitions
,它会过滤出所有配置类,然后循环解析每个配置类并注册配置类的bean定义。总览 processConfigBeanDefinitions 源码:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//从BeanDefinitionRegistry中取注册的全部bean名
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// checkConfigurationClassCandidate判断一个类是否配置类,并为BeanDefinition设置属性lite或full
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 按照 Order 值排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 设置 beanName 生成器
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
// 没有手动设置 beanName 生成器
if (!this.localBeanNameGeneratorSet) {
// 从单例获取 beanName 生成器,默认是没有的,返回null
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
// 创建配置类解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//配置类解析,在此处会解析配置类上的注解(ComponentScan扫描出的类,@Import注册的类,以及@Bean方法定义的类)
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//Bean定义注册
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
// 判断reader.loadBeanDefinitions(configClasses)有没有添加新的anDefinition
// 若有,则nDefinitionCount()大于candidateNames.length
//则需要把新加入的还没有被解析过的bean重新加入到candidates变量中,重新执行一遍配置类解析和Bean定义注册
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
// 未解析的类添加到candidates中,就会进入到下一次的while的循环
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
5.3.2 判断候选配置类
checkConfigurationClassCandidate 方法判断一个类是否配置类,并为BeanDefinition设置属性lite或full。Spring 文档说明了 @Configuration 的 lite 模式或 full 模式
。简单说就是 @Bean 方法的返回值会注入到容器中,如果 @Bean 方法所在的类被 @Configuration 标注,就是full模式,这种模式会给配置类通过 CGLIB 生成一个代理,所有 @Bean 标注的方法都是通过代理进行的;如果 @Bean 方法所在类被 @Configuration 以外注解如 @Component 标注,或被 Configuration 标注,但它的属性 proxyBeanMethods 是false,就是 lite 模式,这种模式不会生成代理,某个 @Bean 方法中如果需要其他 @Bean 方法返回的对象,就要从容器中取出一个新对象了。
abstract class ConfigurationClassUtils {
public static final String CONFIGURATION_CLASS_FULL = "full";
public static final String CONFIGURATION_CLASS_LITE = "lite";
public static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final String ORDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "order");
private static final Set<String> candidateIndicators = new HashSet<>(8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
// if ...else if...else 解析元数据,具体请看源代码
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// full 模式:类上有 @Configuration 注解,并且 proxyBeanMethods 字段为 true
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// lite 模式: 类上有 @Configuration 且 proxyBeanMethods 为 false 或者 类上有 @Component、@ComponentScan、@Import、@ImportResource
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// 设置排序属性
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
// 不处理接口或注解
if (metadata.isInterface()) {
return false;
}
// 判断类上是否有 @Component、@ComponentScan、@Import、@ImportResource
for (String indicator : candidateIndicators) {
if (metadata.isAnnotated(indicator)) {
return true;
}
}
// 判断类中是否有 @Bean 注解的方法
return hasBeanMethods(metadata);
}
static boolean hasBeanMethods(AnnotationMetadata metadata) {
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
catch (Throwable ex) {
log.....
return false;
}
}
@Nullable
public static Integer getOrder(AnnotationMetadata metadata) {
Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);
}
public static int getOrder(BeanDefinition beanDef) {
Integer order = (Integer) beanDef.getAttribute(ORDER_ATTRIBUTE);
return (order != null ? order : Ordered.LOWEST_PRECEDENCE);
}
}
5.3.3 配置类解析
ConfigurationClassParser 的 parse 分两步,重载的parse方法解析配置类、解析 DeferredImportSelector 指定的类
:
class ConfigurationClassParser {
private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 1、解析配置类,根据 Bean 定义类型,调用重载的 parse 方法
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 2. 解析 DeferredImportSelectorHandler 指定的类
this.deferredImportSelectorHandler.process();
}
}
重载的 parse方法
会解析配置类上的注解(@ComponentScan,@Import,@Bean等等),解析完以后把结果放入到parse的缓存configurationClasses中去。每个重载的parse方法,如下面的,先把入参封装成ConfigurationClass,然后调processConfigurationClass。
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected final void parse(Class<?> clazz, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
ConfigurationClass是配置类的一种模型
,为了解析配置类上加的注解,它设计了几种属性:
final class ConfigurationClass {
private final AnnotationMetadata metadata;
private final Resource resource;
@Nullable
private String beanName;
//@Import相关
private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
//@Bean
private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
//@ImportResource相关
private final Map<String, Class<? extends BeanDefinitionReader>> importedResources = new LinkedHashMap<>();
//@Import导入的ImportBeanDefinitionRegistrar
private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars = new LinkedHashMap<>();
final Set<String> skippedBeanMethods = new HashSet<>();
//...
}
5.3.3.1 processConfigurationClass
每个配置类的解析都会执行processConfigurationClass,解析完放到缓存configurationClasses中。配置类如果有父类,就循环解析。其中SourceClass是对ConfigClass这个模型的简单包装
,是为了以统一的方式处理配置类,而不管它是如何加载。
//缓存
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// @Condition 注解逻辑判断,如果有 @Condition 条件不满足,就不解析了
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 配置类可能有父类,循环处理,doProcessConfigurationClass会返回父类
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 真正解析配置类的方法
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 放入缓存
this.configurationClasses.put(configClass, configClass);
}
5.3.3.2 doProcessConfigurationClass
doProcessConfigurationClass 具体做了以下8种处理工作:
- 处理配置类的内部类
- 处理配置类上的 @PropertySource 注解
- 解析配置类的 @ComponentScan 和 @ComponentScans 注解,然后根据这2种注解配置的包扫描路径,利用 ASM 技术扫描出所有需要注入的类。如果扫描出的类也加了 @ComponentScan 和 @ComponentScans,就递归扫描,直到所有加了这两个注解的类都被解析。
- 处理@Import注解,具体有三种解析方式。
- 处理@ImportResource注解。
- 处理配置类中标注@Bean的方法。
- 处理接口默认方法加@Bean的情况。
- 解析配置类的父类。
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
// 1. @Component标注的类,其内部类也是属于配置类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 解析内部配置类,递归处理
processMemberClasses(configClass, sourceClass, filter);
}
// 2. 处理加了@PropertySource的配置类
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 3. 处理@ComponentScan或者@ComponentScans注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// @ComponentScan和@ComponentScans指明的的扫描的包里面的类
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 扫面出来的bean如果也有这2种注解,用parse递归解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 4. 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 5. 处理@ImportResource注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
// 解析出locations属性指定的文件
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 6. 处理@Bean标注的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 7. 处理接口默认方法加@Bean
// JDK8,接口有默认方法,默认方法有@Bean的处理
processInterfaces(configClass, sourceClass);
// 8. 解析父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 有父类就返回父类
return sourceClass.getSuperClass();
}
}
// 没有父类返回null
return null;
}
目前我们就先分析到这,再详细的分析可以看https://juejin.cn/post/7448889636338696211
6、Aware 接口
1. Aware 接口用于注入一些与容器相关信息,例如
a. BeanNameAware 注入 bean 的名字
b. BeanFactoryAware 注入 BeanFactory 容器
c. ApplicationContextAware 注入 ApplicationContext 容器
d. EmbeddedValueResolverAware ${}
2、上述的 b、c、d 的功能用 @Autowired 就能实现,为啥还要用 Aware 接口呢:
简单的说:
a. @Autowired 的解析需要用到 bean 后处理器,属于扩展功能
b. 而 Aware 接口属于内置功能,不加任何扩展,Spring 就能识别
3、配置类@Autowired失效分析
输出显示,@Autowired 和 @PostConstruct 失效了,未输出日志
问题分析:
Java 类不包含 BeanPostProcessor 的情况:
java配置类包含BeanFactoryPostProcessor的情况,因此要创建其中的BeanFactoryPostProcessor必须提前创建Java配置类,而此时BeanPostProcessor还没准备好,也就导致@Autowired等注解失效
7、初始化与销毁
Spring 提供的初始化和销毁方式都是三种
- 初始化(执行顺序如下)
- @PostConstruct
- 实现 InitializingBean
- @Bean(initMethod = "init")
- 销毁(执行顺序如下)
- @PreDestroy
- 实现 DisposableBean
- @Bean(destroyMethod = "destory")
代码示例
8、Scope
Scope 类型有哪些
- singleton:默认作用域,每个Spring 容器种只有一个实例,适用于无状态Bean,如工具类、配置类。
- prototype:每次请求都会创建一个实例,适用于有状态的Bean,如用户会话、请求处理类。
- request:每个 Http 请求创建一个实例,仅在Web应用中有效,适用于请求级别的数据,如表单提交。
- session:每个 Http 绘画创建一个实例,仅在Web应用中有效。适用于用户会话数据,如登录信息。
- application:每个 ServletContext 创建要给实例,仅在Web应用中有效。适用于全局共享数据,如应用配置。
scope 失效分析
singletonBean注入prototypeBean,在获取prototypeBean时,发现时同一个对象
解决方法:
- 注入prototypeBean 加上 @Lazy
- prototypeBean的类上 @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
- 注入prototypeBean 使用 ObjectFactory<Bean> bean
- 注入 ApplicationContext,用ApplicationContext.getBean(class)
1 和 2 是使用代理,3 和 4 没有使用代理
解决方法虽有不同,但理念上殊途同归,都是推迟其他 scope bean 的获取