Spring-Ioc之bean注入-singleton
大家知道spring-ioc的bean注入是其核心模块。其中包括了beanDefinition的创建,bean的生命周期,特殊情况的bean-aop。最终形成的bean会有不同的scope熟悉。这里就先详细分析一下singleton-scope情况下,bean是如何通过spring的反射机制来实现注入的。
代码版本
spring 5.0.8
jdk 1.8
源码片段
这里会贴出进行本次分析的源码片段
1.启动类的main方法
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigTest.class);
ctx.refresh();
BeanTest beanTest = ctx.getBean(BeanTest.class);
String name = beanTest.getName();
System.out.println(name);
}
2.简单bean
public class BeanTest {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.简单配置类
@Configuration
public class ConfigTest {
@Bean
public BeanTest getBeanTest(){
BeanTest beanTest = new BeanTest();
beanTest.setName("ok");
return beanTest;
}
}
分析目的
了解一个最简单单例bean的实例化过程
分析步骤
- 调用链图解
- 核心代码分析
调用链图解
序号 | 作用 | 类 | 方法 | 方法执行行数 |
---|---|---|---|---|
1 | AbstractApplicationContext | refresh() | 549 finishBeanFactoryInitialization(beanFactory); | |
2 | AbstractApplicationContext | finishBeanFactoryInitialization(…) | 868 beanFactory.preInstantiateSingletons() | |
3 | DefaultListableBeanFactory | preInstantiateSingletons() | 758 getBean(beanName); | |
4 | AbstractBeanFactory | doGetBean(…) | 315 sharedInstance = getSingleton(beanName, () -> { | |
5 | DefaultSingletonBeanRegistry | getSingleton(…) | 222 singletonObject = singletonFactory.getObject(); | |
6 | 这里根据不同的scope执行不同的处理代码 | AbstractBeanFactory | doGetBean(…) | 317 return createBean(beanName, mbd, args); |
7 | AbstractAutowireCapableBeanFactory | createBean(…) | 495 Object beanInstance = doCreateBean(beanName, mbdToUse, args); | |
8 | AbstractAutowireCapableBeanFactory | doCreateBean(…) | 535 instanceWrapper = createBeanInstance(beanName, mbd, args); | |
9 | AbstractAutowireCapableBeanFactory | createBeanInstance(…) | 1095 if (mbd.getFactoryMethodName() != null) { | |
10 | AbstractAutowireCapableBeanFactory | instantiateUsingFactoryMethod(…) | 1247 return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); | |
11 | 通过参数匹配找到并执行工厂方法 | ConstructorResolver | instantiateUsingFactoryMethod(…) | 581 beanInstance = this.beanFactory.getInstantiationStrategy().instantiate |
12 | 这个方法是创建bean对象,最终执行反射的地方 | SimpleInstantiationStrategy | instantiate |
核心代码分析
SimpleInstantiationStrategy.instantiate
public class SimpleInstantiationStrategy implements InstantiationStrategy {
...
//这个方法是创建bean对象,最终执行反射的地方。
//部分参数说明
//beanName getBeanTest
//factoryBean {ConfigTest$$EnhancerBySpringCGLIB$$b5d90a6e}注意这里,所有@Configuration类在启动时都使用CGLIB进行子类化
//factoryMethod public com.kaxudodo.demo.BeanTest com.kaxudodo.demo.ConfigTest.getBeanTest()
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, @Nullable Object... args) {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
}
else {
//使给定方法可访问,必要时明确设置它可访问。
ReflectionUtils.makeAccessible(factoryMethod);
}
//这里获取为空
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
//将方法对象放入当前 ThreadLocal<Method> currentlyInvokedFactoryMethod
currentlyInvokedFactoryMethod.set(factoryMethod);
//通过反射生成对象bean
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null)