概念
什么是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对象。