程序员社区

Spring 框架源码解读10


title: Spring 框架源码解读10
date: 2020/04/19 13:34


本节内容 & 思考题

带大家实现注解版的依赖注入,当然是对 @Resource 注解的支持,因为 @Autowired 是根据类型注入,现有基础上实现起来有点麻烦。

还记得我们之前采用了 BeanPostProcesser 实现对 @PostConstruct 注解的处理,在 Spring 中,它采用了下面这个类对 JAS-WS 规范进行支持。

/**
 * 主要处理@Resource、@PostConstruct和@PreDestroy注解的实现
 * <p>
 * Resource的处理是由它自己完成,其它两个是由它的父类完成
 * <p>
 * 父类InitDestroyAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法会找出被@PostConstruct和@PostDestroy注解修饰的方法
 */
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

对 @Autowired 注解的处理由 AutowiredAnnotationBeanPostProcessor 实现。

开始吧

1、新建接口 InstantiationAwareBeanPostProcessor

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * 后置处理注入属性
     */
    void postProcessPropertyValues(Object bean, String beanName);
}

2、实现它,对注解进行处理

public class ResourcePostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {

    private BeanFactory beanFactory;

    /**
     * 后置处理注入属性
     */
    @Override
    public void postProcessPropertyValues(Object bean, String beanName) {
        for (Field field : bean.getClass().getDeclaredFields()) {
            Resource annotation = AnnotationUtil.getAnnotation(field, Resource.class);
            if (ObjectUtil.isNotNull(annotation)) {
                Object fieldRef = beanFactory.getBean(field.getName());
                ReflectUtil.setFieldValue(bean, field, fieldRef);
            }
        }
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
}

BeanFactoryAware 我相信以大家的聪明才智,肯定知道怎么写的。

3、注册到 BF 中

JsonBeanFactoryImpl 里添加,我相信大家也肯定知道的。

Spring 5.0

回忆下我们讲依赖注入时的代码

Spring 框架源码解读10插图
AbstractAutowireCapableBeanFactory#doCreateBean

当时没有带大家看后面的代码,今天简单的带大家过一下:

Spring 框架源码解读10插图1
Spring 框架源码解读10插图2
调用实现了 InstantiationAwareBeanPostProcessor 的后置处理器方法

以 AutowiredAnnotationBeanPostProcessor 为例,Resource 和 Inject 注解的解析基本一样。

Spring 框架源码解读10插图3

先看第一句:

Spring 框架源码解读10插图4

读取当前类所需要的依赖存入 metadata 中,pvs 的作用是为了检查这个字段是否已经在 xml 中配置了。

第二句最终调用到了这里

Spring 框架源码解读10插图5
Spring 框架源码解读10插图6

扩展:todo

还记的我们讲循环依赖里的第三级缓存吗:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                if (exposedObject == null) {
                    return null;
                }
            }
        }
    }
    return exposedObject;
}

AutowiredAnnotationBeanPostProcessor 就实现了 SmartInstantiationAwareBeanPostProcessor。

但是为啥 Autowired 的处理要在这里呢。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » Spring 框架源码解读10

一个分享Java & Python知识的社区