<font style="color:rgb(51, 51, 51);">Spring</font>
<font style="color:rgb(51, 51, 51);">Spring</font>
<font style="color:rgb(51, 51, 51);">Bean</font>
<font style="color:rgb(51, 51, 51);">Spring</font>
<font style="color:rgb(51, 51, 51);">BeanFactory</font>
<font style="color:rgb(51, 51, 51);">ApplicationContext</font>
**<font style="color:rgb(51, 51, 51);">ApplicationContext</font>**
<font style="color:rgb(51, 51, 51);">@ComponentScan</font>
- ````
首先解决给定一个包名,如何获取该包下的所有类的问题;
基本思路就是文件扫描,将文件路径拼接为类名,比如:com.example.hello
。
2025年1月2日15:40:34
❓但对于源码中 classLoader.getResource()等内容不是特别理解
目前的理解就是 classLoader 会去扫描环境变量中 classPath 路径下的包。
创建Bean Definition
为要创建的 BeanBeanDefinition
public class BeanDefinition {
// 全局唯一的Bean Name:
String name;
// Bean的声明类型:
Class<?> beanClass;
// Bean的实例:
Object instance = null;
// 构造方法/null:
Constructor<?> constructor;
// 工厂方法名称/null:
String factoryName;
// 工厂方法/null:
Method factoryMethod;
// Bean的顺序:
int order;
// 是否标识@Primary:
boolean primary;
// init/destroy方法名称:
String initMethodName;
String destroyMethodName;
// init/destroy方法:
Method initMethod;
Method destroyMethod;
}
创建Bean实例
本部分主要解决的是在有了 beanDefination,如何创建 bean:
首先我们来看看spring 中支持的四种依赖注入的方式:
- 构造方法注入
- 工厂方法注入
setter
方法注入- 字段注入
在这里,构造方法注入和工厂方法注入,Bean的创建与注入是一体的,而后两种方式,即setter
方法注入和属性注入,Bean的创建与注入是可以分开的,即先创建Bean实例,再用反射调用方法或字段,完成注入。
我们把前两种方式称为强依赖,后两种方式称为弱依赖。
再来看看循环依赖的问题,Spring ioc 可以解决部分循环依赖的问题,但对于对于强依赖的循环依赖,是无法处理的,因为我们自己写 java 代码也无法处理这种情况,比如下边代码所示情况:
class A {
final B b;
A(B b) { this.b = b; }
}
class B {
final A a;
B(A a) { this.a = a; }
}
所以,对于IoC容器来说,创建Bean的过程分两步:
- 创建Bean的实例,此时必须注入强依赖;
- 对Bean实例进行Setter方法注入和字段注入。
第一步如果遇到循环依赖则直接报错,第二步则不需要关心有没有循环依赖(已经创建出 Bean 实例的话,那肯定可以解决循环依赖的问题)。
首先,我们先完成强依赖类型的 bean 的创建:
那么,创建 bean 实例的主要流程如下,这里先创建 Configuration 类型的 bean,再去创建普通 bean。因为 Configuration 标注的 bean 实际上是工厂 bean,内部通过 实例方法创建其他的 bean,所以必须先对他们进行实例化;
public AnnotationConfigApplicationContext(Class<?> configClass, PropertyResolver propertyResolver) {
this.propertyResolver = propertyResolver;
// 扫描获取所有Bean的Class类型:
final Set<String> beanClassNames = scanForClassNames(configClass);
// 创建Bean的定义:
this.beans = createBeanDefinitions(beanClassNames);
// 创建BeanName检测循环依赖:
this.creatingBeanNames = new HashSet<>();
// 创建@Configuration类型的Bean:
this.beans.values().stream()
// 过滤出@Configuration:
.filter(this::isConfigurationDefinition).sorted().map(def -> {
createBeanAsEarlySingleton(def);
return def.getName();
}).collect(Collectors.toList());
// 创建其他普通Bean:
List<BeanDefinition> defs = this.beans.values().stream()
// 过滤出instance==null的BeanDefinition:
.filter(def -> def.getInstance() == null)
.sorted().collect(Collectors.toList());
// 依次创建Bean实例:
defs.forEach(def -> {
// 如果Bean未被创建(可能在其他Bean的构造方法注入前被创建):
if (def.getInstance() == null) {
// 创建Bean:
createBeanAsEarlySingleton(def);
}
});
}
剩下的工作,就是将createBeanAsEarlySingleton()
public Object createBeanAsEarlySingleton(BeanDefinition def) {
// 检测循环依赖:
if (!this.creatingBeanNames.add(def.getName())) {
throw new UnsatisfiedDependencyException();
}
// 创建方式:构造方法或工厂方法:
Executable createFn = def.getFactoryName() == null ?
def.getConstructor() : def.getFactoryMethod();
// 创建参数:
Parameter[] parameters = createFn.getParameters();
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
// 从参数获取@Value和@Autowired:
Value value = ...
Autowired autowired = ...
// 检查Value和Autowired
...
// 参数类型:
Class<?> type = param.getType();
if (value != null) {
// 参数设置为查询的@Value:
args[i] = this.propertyResolver.getRequiredProperty(value.value(), type);
} else {
// 参数是@Autowired,查找依赖的BeanDefinition:
BeanDefinition dependsOnDef = name.isEmpty() ? findBeanDefinition(type) : findBeanDefinition(name, type);
// 获取依赖Bean的实例:
Object autowiredBeanInstance = dependsOnDef.getInstance();
if (autowiredBeanInstance == null) {
// 当前依赖Bean尚未初始化,递归调用初始化该依赖Bean:
autowiredBeanInstance = createBeanAsEarlySingleton(dependsOnDef);
}
// 参数设置为依赖的Bean实例:
args[i] = autowiredBeanInstance;
}
}
// 已拿到所有方法参数,创建Bean实例:
Object instance = ...
// 设置实例到BeanDefinition:
def.setInstance(instance);
// 返回实例:
return def.getInstance();
}
完成了强依赖类型 bean 的创建,下一步是完成****
`@Value``@Autowired`public AnnotationConfigApplicationContext(Class<?> configClass, PropertyResolver propertyResolver) {
...
// 通过字段和set方法注入依赖:
this.beans.values().forEach(def -> {
injectBean(def);
});
// 调用init方法:
this.beans.values().forEach(def -> {
initBean(def);
});
}
Aop
首先实现AOP需要用户提供的两个Bean:
- 原始Bean,即需要被代理的Bean;
- 拦截器,即拦截了目标Bean的方法后,会自动调用拦截器实现代理功能。
注:本教程实现的AOP的API与Spring
框架层面需要实现的:
ProxyResolver
创建AOP代理的工具类;AroundProxyBeanPostProcessor
核心AOP实现逻辑,实现查找Bean、创建AOP代理类等逻辑;