Autowired注解可以应用在构造方法,普通方法,参数,字段,以及注解这五种类型的地方,它的保留策略是在运行时
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* Defaults to {@code true}.
*/
boolean required() default true;
}
public enum Autowire {
/**
* Constant that indicates no autowiring at all.
* 常量,表示没有自动装配
*/
NO(AutowireCapableBeanFactory.AUTOWIRE_NO),
/**
* Constant that indicates autowiring bean properties by name.
* 常量,表示按名称自动装配
*/
BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),
/**
* Constant that indicates autowiring bean properties by type.
* 常量,表示按类型自动装配
*/
BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
private final int value;
Autowire(int value) {
this.value = value;
}
public int value() {
return this.value;
}
/**
* Return whether this represents an actual autowiring value.
* @return whether actual autowiring was specified
* (either BY_NAME or BY_TYPE)
* 是否自动装配?按名称或按类型
*/
public boolean isAutowire() {
return (this == BY_NAME || this == BY_TYPE);
}
}
(1).InjectionMetadata可以看作是一个工具类,用于处理自动装配元数据
(2).InjectionMetadata中有一个 InjectedElement 的抽象静态内部类,用于表示单个的注入元素,其中最重要的就是 inject 方法,用于处理注入逻辑,这个注入逻辑分为字段注入和方法注入(主要是构造函数)
public abstract static class InjectedElement {
/**
* 类中的一个成员(字段或方法)或构造函数
* 实现了 {@link java.lang.reflect.Member} 接口的类:
* {@link java.lang.reflect.Constructor} - 构造器
* {@link java.lang.reflect.Executable} - 可执行的类型,是Constructor和Method的父类
* {@link java.lang.reflect.Field} - 属性
* {@link java.lang.reflect.Method} - 方法
*/
protected final Member member;
/**
* 是否是字段 布尔标识
*/
protected final boolean isField;
/**
* 属性描述
*/
@Nullable
protected final PropertyDescriptor pd;
/**
* 是否跳过 布尔标识
*/
@Nullable
protected volatile Boolean skip;
protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
this.member = member;
this.isField = (member instanceof Field);
this.pd = pd;
}
public final Member getMember() {
return this.member;
}
/**
* 获取源类型
*
* @return Class
*/
protected final Class> getResourceType() {
if (this.isField) {
return ((Field) this.member).getType();
} else if (this.pd != null) {
return this.pd.getPropertyType();
} else {
return ((Method) this.member).getParameterTypes()[0];
}
}
/**
* 检查源类型
*
* @param resourceType 源类型字节码
*/
protected final void checkResourceType(Class> resourceType) {
// 如果是字段
if (this.isField) {
Class> fieldType = ((Field) this.member).getType();
/*
* isAssignableFrom() 方法是判断是否为某个类的父类 父类.class.isAssignableFrom(子类.class)
* 如果 resourceType 不是 fieldType 的父类 且 fieldType 不是 resourceType 的父类,抛出异常
*/
if (!(resourceType.isAssignableFrom(fieldType) || fieldType.isAssignableFrom(resourceType))) {
throw new IllegalStateException("Specified field type [" + fieldType +
"] is incompatible with resource type [" + resourceType.getName() + "]");
}
} else {
Class> paramType =
(this.pd != null ? this.pd.getPropertyType() : ((Method) this.member).getParameterTypes()[0]);
if (!(resourceType.isAssignableFrom(paramType) || paramType.isAssignableFrom(resourceType))) {
throw new IllegalStateException("Specified parameter type [" + paramType +
"] is incompatible with resource type [" + resourceType.getName() + "]");
}
}
}
/**
* Either this or {@link #getResourceToInject} needs to be overridden.
*
* inject 执行注入逻辑,分 字段 和 方法 进行处理
*/
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
// 使属性可访问,可以称之为暴力破解的方法,但反射技术本就是为框架等用途设计的,这也无可厚非
ReflectionUtils.makeAccessible(field);
// 注入值
field.set(target, getResourceToInject(target, requestingBeanName));
} else {
// 如果已指定显式属性值,跳过
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
/**
* 检查属性值 double check!
*/
protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
// 如果 this.skip 非空,返回 skip,如果 pvs 为空,将 this.skip 置为 false 并返回
Boolean skip = this.skip;
if (skip != null) {
return skip;
}
if (pvs == null) {
this.skip = false;
return false;
}
synchronized (pvs) {
skip = this.skip;
if (skip != null) {
return skip;
}
if (this.pd != null) {
// 如果 pvs 包含属性描述的属性名
if (pvs.contains(this.pd.getName())) {
// Explicit value provided as part of the bean definition.
// 作为bean定义的一部分提供的显式值
// 可以跳过,返回
this.skip = true;
return true;
} else if (pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
}
}
this.skip = false;
return false;
}
}
/**
* Clear property skipping for this element.
*
* @since 3.2.13
*/
protected void clearPropertySkipping(@Nullable PropertyValues pvs) {
if (pvs == null) {
return;
}
synchronized (pvs) {
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
}
}
}
/**
* 这个或 inject 需要被重写
*/
@Nullable
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return null;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof InjectedElement)) {
return false;
}
InjectedElement otherElement = (InjectedElement) other;
return this.member.equals(otherElement.member);
}
@Override
public int hashCode() {
return this.member.getClass().hashCode() * 29 + this.member.getName().hashCode();
}
@Override
public String toString() {
return getClass().getSimpleName() + " for " + this.member;
}
}
它实现了真正的自动注入
1.主要字段及其含义:
/**
* 日志记录
*/
protected final Log logger = LogFactory.getLog(getClass());
/**
* 自动装配类型集合,默认的自动装配类型是 Spring 提供的 @Autowired 和 @Value
*/
private final Set> autowiredAnnotationTypes = new LinkedHashSet<>(4);
/**
* 自动装配类型集合
*/
private String requiredParameterName = "required";
/**
* 是否是必须参数,默认 true
*/
private boolean requiredParameterValue = true;
/**
* 优先级
*/
private int order = Ordered.LOWEST_PRECEDENCE - 2;
/**
* 可配置的 bean 工厂,可空
*/
@Nullable
private ConfigurableListableBeanFactory beanFactory;
/**
* 已检查的方法集合
*/
private final Set lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
/**
* 候选的构造函数缓存
*/
private final Map, Constructor>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
/**
* 要注入的元数据缓存
*/
private final Map injectionMetadataCache = new ConcurrentHashMap<>(256);
2.AutowiredAnnotationBeanPostProcessor的构造函数
/**
* 构造函数,初始化所需的数据及记录日志
*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
// 将 Autowired 和 Value 加入自动装配类型集合
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
// 根据名称获取类对象的字节码,转为 Class extends Annotation> 类型
this.autowiredAnnotationTypes.add((Class extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
// 日志记录:JSR-330 'javax.inject.Inject' 注释被发现并支持自动装配
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
} catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
3.setAutowiredAnnotationType 自定义自动装配
/**
* 开闭原则,开发人员可以指定自己的自动装配类型,以指示该成员应该被自动装配
* -------------------------设置自动装配类型----------------------------
* 用于构造函数,字段,setter方法和任意的配置方法
* 默认的 autowired 类型是 Spring 提供的{@link Autowired},以及{@link Value}
* 此setter属性存在,以便开发人员可以提供他们自己的注释类型,以指示该成员应该被自动装配
*/
public void setAutowiredAnnotationType(Class extends Annotation> autowiredAnnotationType) {
// 设置断言,参数不能为空
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
// 将默认的自动装配类型清除,默认为 Spring 提供的 @Autowired 和 @Value
this.autowiredAnnotationTypes.clear();
// 设置自己的自动装配类型
this.autowiredAnnotationTypes.add(autowiredAnnotationType);
}
/**
* 批量设置自动装配类型,接收一个 Set> 集合
*/
public void setAutowiredAnnotationTypes(Set> autowiredAnnotationTypes) {
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
}
4.设置 bean 工厂,bean可以立即调用工厂中的方法,该方法是 BeanFactoryAware 接口中的方法
@Override
public void setBeanFactory(BeanFactory beanFactory) {
// 如果该 bean 工厂没有实现 ConfigurableListableBeanFactory 接口,或不是 ConfigurableListableBeanFactory 类型
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
}
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
5.postProcessMergedBeanDefinition 该方法在bean 刚刚初始化完 但在属性填充之前调用
/**
* bean定义后置处理器,这个方法执行时间的节点是在创建bean的实例后 在populateBean()方
* 法调用前调用的,主要完成的功能就是找出带有特定注解的field method 并记录在数据结构中,
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
// 找出所有的字段或者方法上的@Autowired @Value @Inject注解 并保存
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 加入到BeanDefinition
metadata.checkConfigMembers(beanDefinition);
}
6.postProcessPropertyValues 属性值后置处理器
/**
* findAutowiringMetadata()方法这里获取注入元数据信息,
* 然后调用InjectionMetadata.inject()的方法。
* 在以参数注入就是调用AutowiredFieldElement.inject()方法
* 属性值执行后置器 执行的时间节点是在 populateBean() 之后
*
* @param pvs 名为beanName的Bean的参数值数组
* @param pds 名为beanName的Bean的参数内容描述数组
* @param bean 实例化的对象
* @param beanName 实例化的对象名
* @return pvs 属性值数组
* @throws BeanCreationException 创建Bean异常
*/
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 从缓存中读出
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 注入
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;
}
7.findAutowiringMetadata 查找自动装配元数据 这是Spring对扩展的开放,可以使用自定义注解标识自动装配,Spring将在这里进行扫描
/**
* 查找自动装配元数据
*/
private InjectionMetadata findAutowiringMetadata(String beanName, Class> clazz, @Nullable PropertyValues pvs) {
// 回退到类名作为缓存键,以便与自定义调用者向后兼容
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 从要注入的元数据缓存中根据键查找
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
/*
* 如果 metadata 为空 或者 metadata.targetClass != clazz ,即从缓存中找到的元数据没有或不对应
* -----------------------------------------------------------------------------------
* double check !
*/
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
// 如果 metadata 需要刷新,即当 metadata 为空 或者 metadata.targetClass != clazz
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
// 当 metadata.targetClass != clazz 时,即所需元数据与目标数据不一致时
if (metadata != null) {
metadata.clear(pvs);
}
// 构建自动装配元数据
metadata = buildAutowiringMetadata(clazz);
// 把注入信息放到this.injectionMetadataCache上
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
//否则 metadata就是需要的元数据,直接返回
return metadata;
}
8.buildAutowiringMetadata 构建自动装配元数据
private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
// 注入元素列表
List elements = new ArrayList<>();
// 目标 Class
Class> targetClass = clazz;
do {
// 当前元素列表
final List currElements = new ArrayList<>();
// 遍历所有的声明了的 field
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 查找可以自动装配的注解
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
// 忽略静态属性的注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 判断是否指定了 required
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历所有的声明了的 方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 用@Autowired修饰的注解可能不止一个,因此都加在 elements 这个容器里面,一起处理
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 将解析后的内容封装成包含所有带有 @Autowired 注解修饰的一个 InjectionMetadata 对象后返回
return new InjectionMetadata(clazz, elements);
}
9.findAutowiredAnnotation 查找可以自动装配的注解
@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
// autowiring annotations have to be local
if (ao.getAnnotations().length > 0) {
for (Class extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
10.AutowiredFieldElement 可以看作注入字段工具类
/**
* Class representing injection information about an annotated field.
* 注入字段类,继承抽象类
* 继承自{@link org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement }
* 重写其中的 inject 方法实现 字段 注入,
*/
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
private final boolean required;
private volatile boolean cached = false;
@Nullable
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, null);
this.required = required;
}
@Override
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);
} else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 通过BeanFactory的resolveDependency()方法解决依赖的值。也就是这个参数需要注入的值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
} else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
// 这里就是通过反射设置参数可见性,然后把值设置到该参数上。
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
11.AutowiredMethodElement
和 AutowiredFieldElement 类似,处理方法注入
这里 AutowiredFieldElement和 AutowiredMethodElement 并没有完全重写 inject 方法,而是将抽象父类中的注入逻辑分为2个实现类分别实现字段注入和方法注入,各司其职,体现了单一职责原则。Spring中用到的设计模式和设计理念很多,仅仅在 AutowiredAnnotationBeanPostProcessor 中就有单一职责原则、开闭原则 和 double-check 等