Java-Spring框架中@Autowired的底层实现

概念

什么是spring:Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。

什么是自动装配:spring中提供了向Bean中自动注入依赖的功能,这个过程就是自动装配,当向bean中注入的内容非常多的时候,自动注入依赖的功能将极大的节省注入程序的时间。

自动装配实现的两种方式:

1.xml配置文件 如图1

基于xml文件的自动装配:byType(类型),byName(名称), constructor(根据构造函数)

图1.xml配置文件实现自动装配

2.基于注解 如图2

基于注解的自动装配:@Autowired,@Resource,@Value

 图2.基于注解自动装配

@Autowired的底层实现

首先我们去ClassPathXmlApplicationContext类的构造方法,这个方法就是底层代码初始化IOC的方法。每一个被@Autowired修饰的变量会在调用这个方法的时候被初始化。

其它代码是对资源的判断,这时候注意refresh方法,这是初始化的方法。

从这个方法中,在try块,里面又有许多方法,其中 

this.finishBeanFactoryInitialization(beanFactory);

这个方法在这之前的步骤中构造了一个beanFactory,这个beanFactory中包含了所有我们配置的或是spring默认配置的一些信息,而autowired就是使用这个beanFactory中的信息来进行的,我们再往下一层进入finishBeanFactoryInitialization(beanFactory)方法。

 

 方法的前面也是对资源是否存在做了很多 判断,最后

beanFactory.preInstantiateSingletons();

这个方法调用beanFactory的preInstantiateSingletons()方法进行初始化所有非lazy-init的bean。

我的JDK无法继续打开这个方法,因此找了其它博主的代码

@Override
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) 
            }
            else {
                getBean(beanName);
            }
        }
    }
}
从以上可以看到,最终通过getBean方法去实现new 对象。

这里getBean有很多重载方法,都是接口,这里也没有实现类去看底层代码,找了其它资料,在这个方法中只有一个方法

public Object getBean(String name) throws BeansException {

return doGetBean(name, null, null, false);

}

而doGetBean方法中:

Object sharedInstance = getSingleton(beanName);

有 实例化单例模式的方法getSingleton(beanName);

而继续跟进这个方法,

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
        return singletonObject;
    }
}

里面实例化对象是调用singletonFactory.getObject();

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    ...
    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
}

而在这个方法中,我们能找到这个方法autowireConstructor(beanName, mbd, ctors, null);也就是@Autowired最终实现的方法

protected BeanWrapper autowireConstructor(
        String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
而在这个方法中,我们能看到最终每个被@Autowired注释的对象通过构造函数去完成new对象,那么继续点开这个方法肯定就是对各种数值的判断以及异常处理,不过我们也就解开了@Autowired强大的真面目

总结

@Autowied是spring的重要注解,虽然理解困难,但是它的本质永远是new对象,因为spring的核心思想就是IOC,程序员不需要new对象,只是将控制权给了spring框架,由它在底层通过注解或者配置文件帮我们new对象。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值