Spring-Ioc之bean注入-singleton

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. 调用链图解
  2. 核心代码分析
调用链图解

这里写图片描述

序号 作用 方法 方法执行行数
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) 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值