Spring源码阅读-@Autowired及其实现

Spring源码阅读-@Autowired及其实现

1.@Autowired注解源码

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.
     * <p>Defaults to {@code true}.
     */
    boolean required() default true;
}
2.Autowire 自动注入枚举类,从这里我们可以看出在Spring中自动装配的方式
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);
	}

}
3.InjectedElement

(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.
         * <p>
         * 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;
        }
    }
4.AutowiredAnnotationBeanPostProcessor (自动装配后置处理器)

它实现了真正的自动注入
1.主要字段及其含义:

    /**
     * 日志记录
     */
    protected final Log logger = LogFactory.getLog(getClass());
    /**
     * 自动装配类型集合,默认的自动装配类型是 Spring 提供的 @Autowired 和 @Value
     */
    private final Set<Class<? extends Annotation>> 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<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
    /**
     * 候选的构造函数缓存
     */
    private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
    /**
     * 要注入的元数据缓存
     */
    private final Map<String, InjectionMetadata> 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<Class< ? extends Annotation>> 集合
     */
    public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> 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<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        // 目标 Class
        Class<?> targetClass = clazz;

        do {
            // 当前元素列表
            final List<InjectionMetadata.InjectedElement> 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<String> 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 等

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值