在一个类中定义一个属性,正常情况下需要在此类中有对此属性赋值的代码,如setter方法,或者在构造函数中赋值,因此类和属性之间的关系已经确定下来了,类和属性间就有了一定的耦合关系。而IOC的精髓就是解耦,类中没有显式的对属性的赋值代码,同时属性的实际类型和值在运行时有系统动态的赋值,Spring对IOC做了很大的扩展,使用者可以很灵活的控制注入的对象类型及值。
Spring内IOC的最直接体现就是@Autowired注解,最常用的方式就是表示在属性上,Spring容器在启动时会将容器内类型是标识了@Autowired的属性类型或者其子类,实现类的Bean通过反射的形式赋值给此属性,或者叫注入的此类中。
Spring中对@Autowired注解的解析是通过一个叫AutowiredAnnotationBeanPostProcessor的BeanPostProcessor(Bean的后处理器)来进行的。BeanPostProcessor负责Bean的一系列处理,实例化前后,初始化前后灯阶段执行相应方法,具体方法的执行顺序如下:
BeanPostPrecessors Invoke Procedure(执行流程)
1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class> beanClass, String beanName);
invoke before doCreateBean(),if the method returns not null,the return Object will as the Bean, avoid invoke doCreateBean() ;
2.SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(Class> beanClass, String beanName);
used to determine to use which Constructor to instance Bean;
3.MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName);
the Bean gets instantiated, modify the RootBeanDefinition ,such as adding PropertyValue etc. before populate Bean;
4.SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(Object bean, String beanName);
invoke before populate Bean,used for resolve Circular Reference;
5.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName);
invoke in populate Bean, but before fill in values,return false will break the opreation for filling values in Bean;
6.InstantiationAwareBeanPostProcessor.postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName);
invoke in populate Bean, but before fill in values,modify the PropertyValues which will be apply for the Bean,
return null will break the opreation for filling values in Bean;
7.BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName);
invoked before invokeInitMethods, modify the finally Bean instance
8.BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName);
invoked after invokeInitMethods, modify the finally Bean instance
使用者可以自己定义自己的BeanPostProcessor,将其以Bean的形式注册到Spring容器中,Spring容器在启动时会执行其相应方法。
AutowiredAnnotationBeanPostProcessor在Spring容器初始化时会最先执行determineCandidateConstructors方法,先看起源码:
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
//此方法的含义是解析Bean类里构造函数上的@Autowired注解,如果有合适的标识了@Autowired的构造函数,
//则在实例化此Bean时会使用此构造函数,@Import和@ComponentScan得到的Bean会如此解析,
//@Bean标识方法生成的Bean不会如此
public Constructor>[] determineCandidateConstructors(Class> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here..
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
catch (NoClassDefFoundError err) {
throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() +
"] for lookup method metadata: could not find class that it depends on", err);
}
this.lookupMethodsChecked.add(beanName);
}
// Quick check on the concurrent map first, with minimal locking.
Constructor>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
//对每个类的构造函数只解析一次,解析完会存储结果,以备下次服用
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor>[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List> candidates = new ArrayList>(rawCandidates.length);
Constructor> requiredConstructor = null;
Constructor> defaultConstructor = null;
for (Constructor> candidate : rawCandidates) {
//查看构造函数上是否标识@Autowired注解,获取注解的属性
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann == null) {
Class> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
//如果此构造函数是重载了父类的构造函数,则寻找父类的构造函数,查看是否标识@Autowired注解,获取注解的属性
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
//当构造函数上存在@Autowired注解
if (ann != null) {
//@Autowired默认的required = true,当有一个required = true的@Autowired标识的构造函数时,
//不能有其他的构造函数再标识@Autowired,否则会报错
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//@Autowired的required的属性值,true / false
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
else if (candidate.getParameterTypes().length == 0) {
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
当没有构造函数标识@Autowired时,设置默认的构造函数作为额外选择
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
} //如果没有默认的无参构造函数,且有@Autowired(required = false)的构造函数,则发出警告信
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor>[candidates.size()]);
} //若只有一个构造函数,且没标识@Autowired,其参数长度>0,将其作为候选者
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) {
candidateConstructors = new Constructor>[] {rawCandidates[0]};
} //没有合适的构造函数
else {
candidateConstructors = new Constructor>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
}
AutowiredAnnotationBeanPostProcessor筛选@Autowired标识的构造函数的代码就是这些,筛选出这些构造函数之后,Spring使用ConstructorResolver这个类来择取合适的构造函数,流程如下:
以上就是@Autowired注解在构造函数上的用法的原理及流程。
重点: BeanFactory的getBean()方法获取scope = singleton的Bean时,不会生成新的Bean对象,
在scope为request及session的生命周期内,Bean的实例化只会触发一次,也就是说@Autowired的标识的构造函数不是每次调用getBean()均会触发执行。只有scope = prototype的Bean,才会每次均执行。