spring中注解方式的自动注入
1 项目xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启包扫描,实际上
BeanDefinitionReader在解析到这个标签的时候会自动向容器中添加5个固定的BeanDefinition
(1)beanName internalConfigurationAnnotationProcessor
与之对应的类 ConfigurationClassPostProcessor
(2)beanName internalEventListenerProcessor
与之对应的类 EventListenerMethodProcessor
(3)beanName internalEventListenerFactory
与之对应的类 DefaultEventListenerFactory
(4)beanName internalAutowiredAnnotationProcessor
与之对应的类 AutowiredAnnotationBeanPostProcessor
(5)beanName internalCommonAnnotationProcessor
与之对应的类 CommonAnnotationBeanPostProcessor
-->
<context:component-scan base-package="cn"></context:component-scan>
<!--在user属性上加入@Autowired注解-->
<bean id="person" class="cn.lx.spring.v1.Person"></bean>
<bean id="user" class="cn.lx.spring.v1.User">
<property name="age" value="12"></property>
<property name="name" value="LX"></property>
</bean>
</beans>
要使用注解,那就必须开启包扫描
2 一些基本类
User
public class User {
private String name;
private String password;
private int age;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Person
public class Person {
@Autowired
private User user;
@Autowired
private List<User> users;
@Value("${java.version}")
private String type;
public Person() {
}
public Person(User user) {
this.user = user;
}
@Autowired
public User test(User user){
System.out.println(user);
return user;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Person{" +
"user=" + user +
", users=" + users +
", type='" + type + '\'' +
'}';
}
}
启动入口
public static void main(String[] args) {
//声明一个可以读取xml配置文件的容器
ClassPathXmlApplicationContext classPathXmlApplicationContext=new
ClassPathXmlApplicationContext();
//设置配置文件
classPathXmlApplicationContext.setConfigLocation("spring-context.xml");
//刷新容器,这是spring中最重要的方法,看懂了这个方法,bean的生命周期也就懂了
classPathXmlApplicationContext.refresh();
Person person = (Person) classPathXmlApplicationContext.getBean("person");
System.out.println(person);
}
启动项目,观察控制台日志打印
15:24:34.384 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 7 bean definitions from class path resource [spring-context.xml]
15:24:34.432 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
15:24:34.482 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
15:24:34.485 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
15:24:34.488 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
15:24:34.491 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
15:24:34.501 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'
15:24:34.558 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User{name='LX', password='null', age=12}
Person{user=User{name='LX', password='null', age=12}, users=[User{name='lx', password='null', age=12}], type='null'}
Process finished with exit code 0
上面日志说的很清楚,容器一共创建了7个bean对象,那么除了我们自己配置的两个bean对象外,另外的5个就只能是包扫描
标签被解析的时候容器自动注册进去的。
3 @Autowired加在属性或普通方法上的自动注入原理
@Autowired
注解自动注入是由AutowiredAnnotationBeanPostProcessor
这个BeanPostProcessor
完成的直接找到这个类的源码,查看他的类图
结合@Autowired
所拥有的功能,可以得到以下几点
(1)
AutowiredAnnotationBeanPostProcessor
间接实现了SmartInstantiationAwareBeanPostProcessor
这个接口,这个接口有一个重要的方法determineCandidateConstructors
,该方法可以在bean实例化的时候返回候选的构造函数,让spring使用这个构造函数实例化对象,所以@Autowired
加载构造方法上可以干预实例化(2)
AutowiredAnnotationBeanPostProcessor
间接实现了InstantiationAwareBeanPostProcessor
这个接口,这个接口方法执行时机我们都知道
postProcessBeforeInstantiation
实例化前(主要是为了返回代理对象)
postProcessAfterInstantiation
属性赋值前
postProcessProperties
属性赋值前(postProcessAfterInstantiation
方法之后)(3)
AutowiredAnnotationBeanPostProcessor
实现了MergedBeanDefinitionPostProcessor
接口,该接口的postProcessMergedBeanDefinition
方法会在bean实例化后进行调用。
经过以上分析,我们得先看MergedBeanDefinitionPostProcessor
接口的方法
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//3.1查找类中的@Autowired和@Value注解,获取注入元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
//3.2将需要自动注入的属性记录到BeanDefinition中
metadata.checkConfigMembers(beanDefinition);
}
自动注入发生在属性赋值阶段,我们直接定位到属性赋值方法
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
/************************安全检查*****************************************************/
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
/*************************************************************************************/
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//InstantiationAwareBeanPostProcessor可以修改实例的属性,不过值有可能会被下面两种自动注入覆盖
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
/************************************************************************************/ //非注解方式自动注入
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
/***********************************注解方式******************************************/
//注解方式的自动注入,我们主要讲这一块的代码
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//此方法完成@Autowired和@Value注解属性自动注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
//下面这个方法已经被废弃掉了,直接忽略
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
/**************************************依赖检查***************************************/
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//统一设置属性
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
完成@Autowired和@Value注解属性自动注入
进入AutowiredAnnotationBeanPostProcessor
的postProcessProperties
方法
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//3.1查找类中的@Autowired和@Value注解,获取注入元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//3.3注入属性
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
3.1查找类中的@Autowired和@Value注解,获取注入元数据
/**
* @param beanName bean的名字
* @param clazz bean的class对象
* @param pvs 需要被赋值的属性集合
*/
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
//获取缓存中对应的注入元数据
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//注入元数据是否需要刷新(判断clazz是否相同)
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//解析clazz,获取类中的注入元数据
metadata = buildAutowiringMetadata(clazz);
//将该类的注入元数据缓存缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
解析clazz,获取类中的注入元数据
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
/**
* AutowiredAnnotationBeanPostProcessor默认构造方法会添加两个注解类到集合中
* this.autowiredAnnotationTypes.add(Autowired.class);
* this.autowiredAnnotationTypes.add(Value.class);
* 这个方法的作用就是判断类中有没有携带这两个注解
* 没有直接返回空
*/
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
//表示一个空的注入元数据
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
/************************************属性上的注解***************************************/
//(1)遍历targetClass类的属性,回调接口方法
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//(2)获取属性上的注解信息
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
//静态属性
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//(3)判断注解中required属性是否为true,没有该属性(@Value)直接false
boolean required = determineRequiredStatus(ann);
//将当前解析的注解信息添加到缓存中
currElements.add(new AutowiredFieldElement(field, required));
}
});
/************************************方法上的注解***************************************/
//(4)遍历targetClass类的方法,回调接口方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//获取方法对应的桥接方法(jvm相关知识点)
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
//获取方法上的注解,和获取属性上的注解方法一模一样
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
//getMostSpecificMethod 将指定类接口方法对象转化为指定类的方法对象
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
//标注在方法上,方法必须有参数
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
//获取注解required属性的值
boolean required = determineRequiredStatus(ann);
//(5)找到当前方法的对应属性描述(解决@Autowired标注在get,set方法上)
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
//缓存
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
//获取父类
targetClass = targetClass.getSuperclass();
}
//它还要对父类里面的属性和方法在判断一次,一直到最顶层Object类
while (targetClass != null && targetClass != Object.class);
//(6)根据注解信息构建注入元数据
return InjectionMetadata.forElements(elements, clazz);
}
(1)遍历targetClass类的属性,回调接口方法
/**
* Invoke the given callback on all locally declared fields in the given class.
* @param clazz the target class to analyze
* @param fc the callback to invoke for each field
* @throws IllegalStateException if introspection fails
* @since 4.2
* @see #doWithFields
*/
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
//遍历属性
for (Field field : getDeclaredFields(clazz)) {
try {
//回调接口方法
fc.doWith(field);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
}
}
}
(2)获取属性上的注解信息
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
//获取该属性的注解数据
MergedAnnotations annotations = MergedAnnotations.from(ao);
//遍历,判断该属性上的注解到底是哪一个(@Autowired,@Value)
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
//无注解,返回null
return null;
}
(3)获取注解中required属性值
/**
* Determine if the annotated field or method requires its dependency.
* <p>A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
/**
* Determine if the annotated field or method requires its dependency.
* <p>A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
* @deprecated since 5.2, in favor of {@link #determineRequiredStatus(MergedAnnotation)}
* 该方法已过时,jdk9以后不再使用该方法
*/
@Deprecated
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
//包含该属性,且属性为true时返回true,否则false
return (!ann.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}
(4)遍历targetClass类的方法,回调接口方法
/**
* Perform the given callback operation on all matching methods of the given
* class, as locally declared or equivalent thereof (such as default methods
* on Java 8 based interfaces that the given class implements).
* @param clazz the class to introspect
* @param mc the callback to invoke for each method
* @throws IllegalStateException if introspection fails
* @since 4.2
* @see #doWithMethods
*/
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
//遍历所有方法
Method[] methods = getDeclaredMethods(clazz, false);
for (Method method : methods) {
try {
//回调接口方法
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
}
}
}
(5)找到当前方法的对应属性描述(解决@Autowired标注在get,set方法上)
实际上就是判断当前方法是不是该类属性对应的set,get方法,如果是,那么就返回这个属性描述,交由处理属性注入的那个分支处理,否则就null,交由处理方法参数注入的那个分支。
/**
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @param clazz the (most specific) class to introspect for descriptors
* @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails
* @since 3.2.13
*/
@Nullable
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
Assert.notNull(method, "Method must not be null");
//获取该类的所有属性描述
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
for (PropertyDescriptor pd : pds) {
//当前方法是不是该属性的get或set方法
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
return pd;
}
}
return null;
}
(6)根据注解信息构建注入元数据
/**
* Return an {@code InjectionMetadata} instance, possibly for empty elements.
* @param elements the elements to inject (possibly empty)
* @param clazz the target class
* @return a new {@link #InjectionMetadata(Class, Collection)} instance,
* or {@link #EMPTY} in case of no elements
* @since 5.2
*/
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
//构建注入元数据
return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
new InjectionMetadata(clazz, elements));
}
3.2将需要自动注入的属性记录到BeanDefinition中
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
//获取被注入元素的属性对象
Member member = element.getMember();
//未记录就记录进去
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
}
}
this.checkedElements = checkedElements;
}
3.3注入属性
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//已经记录的需要自动注入的属性
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
//注入(很明显的多态)
element.inject(target, beanName, pvs);
}
}
}
注入
InjectedElement
有两种类型(属性AutowiredFieldElement
,方法参数AutowiredMethodElement
),它们处理流程是不一样的。
(1)处理属性注入
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
//已经被缓存过了,直接获取缓存中的值
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
//未缓存,从BeanFactory中获取
else {
//根据当前属性对象,初始化一个依赖描述
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取工厂的类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//(3)BeanFactory根据依赖描述去获取容器中的对应的对象(关键方法)
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
//未缓存,开始缓存
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
//将bean之间的依赖关系注册到工厂中
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
}
//反射,强行设置属性值(无论有没有set方法)
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
(2)处理方法参数注入
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
/**
* 判断是否已经手动给该属性赋值,如果是,就直接跳过
*/
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
//获取方法的参数数量
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
//MethodParameter 封装方法参数的帮助类,它的构造方法还可以传入一个参数表示方法的第几个参数
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
//(3)调用同样的方法解析依赖
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
//缓存
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
//将bean之间的依赖关系注册到工厂中
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
//反射执行有@Autowired注解的方法
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
(3)解析依赖(关键方法)
BeanFactory根据依赖描述去获取容器中的对应的对象(关键方法)
这个方法在上一篇文章非注解ByType方式中已经粗略说过了。
在这里详细看一下这个方法
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
/**
* getParameterNameDiscoverer() 获取工厂中的ParameterNameDiscoverer用来解析方法参数名
* initParameterNameDiscovery() 实际上就是将ParameterNameDiscoverer设置到依赖描述中
* 在后面依赖描述会调用ParameterNameDiscoverer来解析方法参数名字
*/
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
/******************************特殊类型,特殊处理**************************************/
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
/***************************************普通类型**************************************/
else {
//(3-1)属性懒加载注入
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//(3-2)直接注入
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
(3-1)属性懒加载注入
这里就和非注解方式的自动注入不一样了,这里会判断在属性上是否添加了@Lazy注解,如果添加了,则返回一个代理对象,否则直接为null。
原本默认的
AutowireCandidateResolver
(自动注入的候选对象解析器)是SimpleAutowireCandidateResolver
类型,但现在你在xml配置文件中配置<context:component-scan base-package="cn"></context:component-scan>
表明你需要使用注解,这样XmlBeanDefinitionReader
在解析到该标签的时候,会自动修改工厂中的AutowireCandidateResolver
,将其更改为可以解析注解的ContextAnnotationAutowireCandidateResolver
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
//懒加载返回null,否则创建代理对象
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
//判断是否懒加载
protected boolean isLazy(DependencyDescriptor descriptor) {
/***************************属性或者方法某个参数相关************************************/
//(3-1-1)获取所有注解信息(属性或者方法某个参数的)
for (Annotation ann : descriptor.getAnnotations()) {
//从当前注解中获取到@Lazy注解
Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
//value=true表示懒加载
if (lazy != null && lazy.value()) {
return true;
}
}
/********************************方法相关*****************************************/
//获取方法参数对象
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
//获取方法对象
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
//MethodParam.getAnnotatedElement()其实就是返回方法对象
//判断方法上面有没有标注@Lazy
//getAnnotation这个方法是重载的
Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
if (lazy != null && lazy.value()) {
return true;
}
}
}
return false;
}
(3-1-1)获取所有注解信息
/**
* Obtain the annotations associated with the wrapped field or method/constructor parameter.
* 又分为两种情况
*/
public Annotation[] getAnnotations() {
//属性
if (this.field != null) {
Annotation[] fieldAnnotations = this.fieldAnnotations;
if (fieldAnnotations == null) {
fieldAnnotations = this.field.getAnnotations();
this.fieldAnnotations = fieldAnnotations;
}
return fieldAnnotations;
}
//方法参数
else {
return obtainMethodParameter().getParameterAnnotations();
}
}
属性
if (this.field != null) { //第一次肯定是null Annotation[] fieldAnnotations = this.fieldAnnotations; if (fieldAnnotations == null) { //Field.getAnnotations()获取属性上的所有注解 fieldAnnotations = this.field.getAnnotations(); //缓存 this.fieldAnnotations = fieldAnnotations; } return fieldAnnotations; }
属性获取注解是非常简单的,这些简单的反射方法需要记住
方法参数
obtainMethodParameter()
就是获取当前依赖描述中方法参数对象/** * Return the wrapped MethodParameter, assuming it is present. * @return the MethodParameter (never {@code null}) * @throws IllegalStateException if no MethodParameter is available * @since 5.0 */ protected final MethodParameter obtainMethodParameter() { Assert.state(this.methodParameter != null, "Neither Field nor MethodParameter"); return this.methodParameter; }
调用
MethodParameter
的getParameterAnnotations
方法获取方法参数的全部注解信息/** * Return the annotations associated with the specific method/constructor parameter. */ public Annotation[] getParameterAnnotations() { Annotation[] paramAnns = this.parameterAnnotations; if (paramAnns == null) { /** * Executable下边有两个子类Constructor,Method * 在这里this.executable中保存的就是方法对象 * method.getParameterAnnotations()方法返回该方法参数的全部注解 * 其中第一个[]代表该方法的第几个参数 * 第二个[]代表这个参数的其中一个注解 */ Annotation[][] annotationArray = this.executable.getParameterAnnotations(); //方法参数的索引 int index = this.parameterIndex; //构造方法 if (this.executable instanceof Constructor && ClassUtils.isInnerClass(this.executable.getDeclaringClass()) && annotationArray.length == this.executable.getParameterCount() - 1) { // Bug in javac in JDK <9: annotation array excludes enclosing instance parameter // for inner classes, so access it with the actual parameter index lowered by 1 index = this.parameterIndex - 1; } /** * adaptAnnotationArray(annotationArray[index]) * 这个方法没干啥,就是直接返回参数 * annotationArray[index]是一个数组,表示当前索引位置方法参数的所有注解 * Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; */ paramAnns = (index >= 0 && index < annotationArray.length ? adaptAnnotationArray(annotationArray[index]) : EMPTY_ANNOTATION_ARRAY); //缓存起来 this.parameterAnnotations = paramAnns; } return paramAnns; }
(3-2)直接注入
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//该方法为空,子类可以重新该方法,实现依赖快速解析
//实际上就是自定义依赖解析逻辑
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
//(3-2-1) 从依赖描述中获取依赖的类型
Class<?> type = descriptor.getDependencyType();
/*****************************@Value注解处理*********************************/
//(3-2-2) 返回依赖描述中包含的value属性的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//(3-2-3) 解析@Value注解
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
/*****************************集合类型处理*********************************/
//(3-2-4) 解析需要注入多个bean的依赖描述(list,set集合这种情况)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
/*****************************普通类型处理*********************************/
//根据type类型获取匹配的bean(见(3-2-4)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
//required=true 必须注入对象,否则抛异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
//required=false可以允许不注入
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//找到了多个类型匹配的bean
if (matchingBeans.size() > 1) {
//(3-2-5) 筛选出同时符合其他条件的bean(如果设置了的话)
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
//抛异常
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
//只有一个类型匹配的bean
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
//非注解方式,instanceCandidate才会是class
if (instanceCandidate instanceof Class) {
//getBean(autowiredBeanName)获取实例
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
//类型不匹配,抛异常
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
(3-2-1) 从依赖描述中获取依赖的类型
/**
* Determine the declared (non-generic) type of the wrapped parameter/field.
* @return the declared type (never {@code null})
* 获取方法参数或属性的类型
*/
public Class<?> getDependencyType() {
/**************************************属性****************************************/
if (this.field != null) {
if (this.nestingLevel > 1) {
Type type = this.field.getGenericType();
for (int i = 2; i <= this.nestingLevel; i++) {
if (type instanceof ParameterizedType) {
Type[] args = ((ParameterizedType) type).getActualTypeArguments();
type = args[args.length - 1];
}
}
if (type instanceof Class) {
return (Class<?>) type;
}
else if (type instanceof ParameterizedType) {
Type arg = ((ParameterizedType) type).getRawType();
if (arg instanceof Class) {
return (Class<?>) arg;
}
}
return Object.class;
}
else {
//获取属性的最外层的类型
return this.field.getType();
}
}
/**************************************方法参数****************************************/
else {
return obtainMethodParameter().getNestedParameterType();
}
}
这个方法处理又是两个分支
属性
这个
nestingLevel
目前还不知道啥意思,就算是List<User>
这种嵌套的,它也会return this.field.getType();
返回List
方法参数
obtainMethodParameter()
这个方法我们已经见过了,就是获取依赖描述中的方法参数对象。主要看
MethodParameter.getNestedParameterType()
这个方法/** * Return the nested type of the method/constructor parameter. * @return the parameter type (never {@code null}) * @since 3.1 * @see #getNestingLevel() */ public Class<?> getNestedParameterType() { /**********************获取方法参数的嵌套类型*****************************/ /** * 首先你得明白nestingLevel这个属性代表的含义 * 它表示的是嵌套的级别,默认为1 * 举个例子,某个方法的参数是List<User> users类型的 * 那么1就代表List,此时就返回List.class * 2代表User,此时就返回User.class */ if (this.nestingLevel > 1) { Type type = getGenericParameterType(); for (int i = 2; i <= this.nestingLevel; i++) { if (type instanceof ParameterizedType) { Type[] args = ((ParameterizedType) type).getActualTypeArguments(); Integer index = getTypeIndexForLevel(i); type = args[index != null ? index : args.length - 1]; } // TODO: Object.class if unresolvable } if (type instanceof Class) { return (Class<?>) type; } else if (type instanceof ParameterizedType) { Type arg = ((ParameterizedType) type).getRawType(); if (arg instanceof Class) { return (Class<?>) arg; } } return Object.class; } /**********************获取方法参数的最外层类型*****************************/ else { return getParameterType(); } } /** * Return the type of the method/constructor parameter. * @return the parameter type (never {@code null}) */ public Class<?> getParameterType() { //首次肯定是null Class<?> paramType = this.parameterType; if (paramType != null) { return paramType; } if (getContainingClass() != getDeclaringClass()) { paramType = ResolvableType.forMethodParameter(this, null, 1).resolve(); } if (paramType == null) { //获取方法参数类型其实很简单,先获取到方法对象,方法对象中就有方法参数类型 paramType = computeParameterType(); } //缓存 this.parameterType = paramType; return paramType; }
(3-2-2) 返回依赖描述中包含的@Value注解value属性的值
/**
* Determine whether the given dependency declares a value annotation.
* @see Value
*/
public Object getSuggestedValue(DependencyDescriptor descriptor) {
//从属性和方法参数的所有注解中找到@Value注解value属性的值
Object value = findValue(descriptor.getAnnotations());
if (value == null) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
//从属性和方法参数的所有注解中找到@Value注解value属性的值
value = findValue(methodPaAram.getMethodAnnotations());
}
}
return value;
}
(3-2-3) 解析@Value注解
public String resolveEmbeddedValue(@Nullable String value) {
if (value == null) {
return null;
}
String result = value;
//遍历工厂中的值解析器,进行解析
for (StringValueResolver resolver : this.embeddedValueResolvers) {
result = resolver.resolveStringValue(result);
if (result == null) {
return null;
}
}
return result;
}
spring在
finishBeanFactoryInitialization
方法中注册了一个和环境相关的值解析器if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); }
(3-2-4) 解析需要注入多个bean的依赖描述(list,set集合这种情况)
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
//获取依赖类型(见7.3(3-2-1))
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
.map(name -> descriptor.resolveCandidate(name, type, this))
.filter(bean -> !(bean instanceof NullBean));
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return stream;
}
/*********************************数组类型************************************/
else if (type.isArray()) {
Class<?> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
/*******************************Collection集合并且是接口*******************************/
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
//(1) 解析依赖描述,获取集合中元素的类型
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
//(2) 根据元素类型,获取匹配的bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
//将注入的bean的名字记录到工厂中
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
//将map集合的values转化为type类型(type是Collection集合)
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
//对list集合进行排序
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
/***************************************Map集合**************************************/
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
(1) 解析依赖描述,获取集合中元素的类型
/** * Build a {@link ResolvableType} object for the wrapped parameter/field. * @since 4.0 */ public ResolvableType getResolvableType() { ResolvableType resolvableType = this.resolvableType; //首次,解析 if (resolvableType == null) { //根据类型构建对应的ResolvableType resolvableType = (this.field != null ? ResolvableType.forField(this.field, this.nestingLevel, this.containingClass) : ResolvableType.forMethodParameter(obtainMethodParameter())); this.resolvableType = resolvableType; } return resolvableType; }
(2) 根据元素类型,获取匹配的bean
/** * Find bean instances that match the required type. * Called during autowiring for the specified bean. * @param beanName the name of the bean that is about to be wired * @param requiredType the actual type of bean to look for * (may be an array component type or collection element type) * @param descriptor the descriptor of the dependency to resolve * @return a Map of candidate names and candidate instances that match * the required type (never {@code null}) * @throws BeansException in case of errors * @see #autowireByType * @see #autowireConstructor */ protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { //调用工具类的方法获取所有requiredType类型的bean的名字 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); /** * this.resolvableDependencies 有4个对象,都是容器内部对象 * ApplicationEventPublisher * ResourceLoader * ApplicationContext * BeanFactory * 这4中类型的属性在此处可以自动注入 */ Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) { Class<?> autowiringType = classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = classObjectEntry.getValue(); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } for (String candidate : candidateNames) { /** * !isSelfReference(beanName, candidate) * 非自身引用(candidate是beanName的FactoryBean这种情况也算自身引用) * * isAutowireCandidate(candidate, descriptor) * 判断candidate是否可以作为自动注入候选 */ if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { //使用getBean(candidate)获取对应的实例,然后再以candidate为key放入result中 //重点看一下这个方法 addCandidateEntry(result, candidate, descriptor, requiredType); } } //说明此时candidate不满足候选条件,需要进行特殊处理 if (result.isEmpty()) { boolean multiple = indicatesMultipleBeans(requiredType); // Consider fallback matches if the first pass failed to find anything... //回退匹配 DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !multiple) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. //自身引用 for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; }
重点看一下
addCandidateEntry
这个方法/** * Add an entry to the candidate map: a bean instance if available or just the resolved * type, preventing early bean initialization ahead of primary candidate selection. */ private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { /*******************************注解走这个分支*********************************/ if (descriptor instanceof MultiElementDescriptor) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); if (!(beanInstance instanceof NullBean)) { candidates.put(candidateName, beanInstance); } } /*****************************非注解方式自动注入走这个****************************/ //candidateName已经实例化 else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor && ((StreamDependencyDescriptor) descriptor).isOrdered())) { //resolveCandidate方法中调用getBean(beanName)获取实例 Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } //candidateName未实例化 else { //此处getType不是实例化,而是获取candidateName对应类型的class对象 candidates.put(candidateName, getType(candidateName)); } }
(3-2-5) 筛选出同时符合其他条件的bean(如果设置了的话)
/**
* Determine the autowire candidate in the given set of beans.
* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
* @param candidates a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param descriptor the target dependency to match against
* @return the name of the autowire candidate, or {@code null} if none found
*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
//有@Primary注解的
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
//有@Priority注解或实现了Priority接口的优先级最高的
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
//不满足上面两种就按名字匹配了
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
由
determineAutowireCandidate
方法,总结如下:
@Autowired
并不单是按类型进行注入,当匹配到多个bean的时候,会遵循如下原则进行筛选(1)有@Primary注解的
(2)有@Priority注解或实现了Priority接口的优先级最高的
(3)不满足上面两种就按名字匹配bean
4 @Autowired加在构造方法上的自动注入原理
@Autowired
注解加在构造方法上,就表明需要使用该构造方实例化对象。AutowiredAnnotationBeanPostProcessor
间接实现了SmartInstantiationAwareBeanPostProcessor
这个接口,这个接口有一个重要的方法determineCandidateConstructors
,这个方法执行完会返回有@Autowired
注解的构造方法(如果required=false
,那么返回的构造方法不止一个),然后调用autowireConstructor(beanName, mbd, ctors, args)
这个方法筛选出最优的构造方法执行自动注入,然后实例化。
下面是spring中bean实例化方法的源码
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//获取需要实例化的bean的类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//工厂方法实例化对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//重新创建对象的快捷方式
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
/********************************构造方法自动注入*******************************/
// Candidate constructors for autowiring?
//4.1返回@Autowired注解标注的构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* ctors != null 说明有@Autowired注解标注的构造方法,此时会执行autowireConstructor方法
* 从ctors中再挑出一个合适的构造方法进行实例化
*/
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//4.2进一步选择合适的constructor实例化对象
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);
}
4.1获取@Autowired注解标注的构造方法
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
/********************************处理@Lookup注解***********************************/
// Let's check for lookup methods here...
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
//获取对应beanName的BeanDefinition
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
//将当前lookup注解标注的方法添加到方法重写列表中
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
this.lookupMethodsChecked.add(beanName);
}
/********************************处理@Autowired构造方法***********************************/
// 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<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
//获取主构造方法(Kotlin classes相关)
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
//遍历构造方法
for (Constructor<?> candidate : rawCandidates) {
//计数加一
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
//获取当前构造方法的@Autowired注解信息(见3.1(2))
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
//获取用户类(解决cglib生成的代理类这种情况)
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
//获取用户类构造方法上的注解信息
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
if (ann != null) {
//此时又来了一个构造方法标注了@Autowired注解,肯定抛异常啊
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取@Autowired注解中required属性的值
boolean required = determineRequiredStatus(ann);
//required属性为true的时候,只能存在一个有@Autowired注解的构造方法
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
//当前构造方法是required构造方法
requiredConstructor = candidate;
}
//将有@Autowired注解的构造方法保存到candidates集合中
candidates.add(candidate);
}
//没有@Autowired注解,并且当前方法参数为0说明是默认构造方法
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
//有加了@Autowired的构造方法
// Add default constructor to list of optional constructors, as fallback.
//required属性为false
if (requiredConstructor == null) {
//将默认构造方法添加到候选构造方法中
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
//不存在默认构造方法,且只有一个构造方法加了@Autowired注解,打印一下日志信息
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("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<?>[0]);
}
//没有加@Autowired的构造方法,且只有一个构造方法,那么就使用当前构造方法
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//没有加@Autowired的构造方法,主构造方法(Kotlin classes相关)不为空,那么就使用primaryConstructor和默认构造方法
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
//没有加@Autowired的构造方法,主构造方法(Kotlin classes相关)不为空,那么就使用primaryConstructor
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
//空的构造方法数组
else {
candidateConstructors = new Constructor<?>[0];
}
//缓存当前解析过的构造方法
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
4.2进一步选择合适的constructor实例化对象
autowireConstructor(beanName, mbd, ctors, args);
这个方法在上一篇文章非注解方式自动注入
中详细解释过,这里就不在赘述了。