https://www.cnblogs.com/leisurexi/p/13263542.html
https://segmentfault.com/a/1190000038251563
一、Spring依赖注入的方式
1.1、手动注入
1.1.1、使用XML的方式进行Setter方式的注入
public class SpringAction {// 注入对象springDaoprivate SpringDao springDao;// 一定要写被注入对象的set方法public void setSpringDao(SpringDao springDao) {this.springDao = springDao;}}
<!--配置bean,配置后该类由spring管理-->
1.1.2、构造器注入
这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:
public class SpringAction {//注入对象springDaoprivate SpringDao springDao;private User user;}
在XML文件中同样不用
<!--配置bean,配置后该类由spring管理--><bean name="springAction" class="com.bless.springdemo.action.SpringAction">
1.2、 自动注入
1.2.1、XML的自动注入
其实Spring也支持bean的自动注入。在定义bean时我们可以通过bean元素的autowire属性来指定是否需要给当前bean来自动注入其所关联的bean。autowire属性的可选值有四个。
public class Hello {public Hello(World world) {}}
<!-- 通过构造方法按照类型进行自动注入 --><bean id="hello" class="com.app.Hello" autowire="constructor"/>
1.2.2、@Autowired自动注入
三、AutowiredAnnotationBeanPostProcessor 类
AutowiredAnnotationBeanPostProcessor是实现@Autowired 功能的主要类,它有一些方法是会用解析 @Autowired 注解并实现自动注入的功能。
3.1、 收集注入元信息
3.1.1、resolveBeforeInstantiation

- 首先在
CreateBean()方法调用resolveBeforeInstantiation()方法,执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法 如果
postProcessBeforeInstantiation返回Bean实例那么直接返回这个实例,如果返回nul 继续调用doCreateBean@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {...try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// 有机会返回一个代理对象。SPring的扩展点Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}// 执行创建Bean的过程Object beanInstance = doCreateBean(beanName, mbdToUse, args);...}@Nullableprotected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;// beforeInstantiationResolved表示该bean实例化前启用实例化后置处理器// 1、Bean的属性中的beforeInstantiationResolved字段是否为true,默认是false。if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// 2、是否是用户定义的而不是应用程序本身定义的,创建AOP时候为true,程序设置// 3、Bean的hasInstantiationAwareBeanPostProcessors属性为true,// 这个属性在Spring准备刷新容器前转换BeanPostProcessors的时候会设置,// 如果当前Bean实现了InstantiationAwareBeanPostProcessor则这个就会是true。if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {// 这里就是调用了BeanPost的前置方法bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {// 这里就是调用了BeanPost的后置方法bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}// 不满足2或者3的时候就会设置为falsembd.beforeInstantiationResolved = (bean != null);}return bean;}
hasInstantiationAwareBeanPostProcessors()参考13-Spring源码refresh-registerBeanPostProcessors
中的代码块3。通过hasInstantiationAwareBeanPostProcessors()方法看有没有InstantiationAwareBeanPostProcessors接口的实现类,如果有,就调用该接口的postProcessBeforeInstantiation方法,如果这个接口有创建返回Bean,再调用BeanPostProcessor接口的postProcessAfterInitialization的方法,这样就完成了Bean的创建。
我们看到如果是在这一阶段通过InstantiationAwareBeanPostProcessor接口产生了Bean返回的话,那其就只会调用BeanPostProcessor接口的postProcessAfterInitialization方法,不会再调用其的例如一些Aware等接口。
如果在上面没有通过InstantiationAwareBeanPostProcessor产生Bean的话,就会接着往下调用doCreateBean(beanName, mbdToUse, args)方法。
通过断点调试, 不难发现, 6个后置处理器中, 满足条件的就三个, 按照执行顺序排列为:
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- AutowiredAnnotationBeanPostProcessor
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter#postProcessBeforeInstantiation
@Override@Nullablepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}
这里 **AutowiredAnnotationBeanPostProcessor **的 **postProcessBeforeInstantiation()** 的方法会被调用,由于**AutowiredAnnotationBeanPostProcessor** 并没有重写这个方法,所以什么都不做。
3.1.2、findAutowiringMetadata 寻找注解元信息
操作 BeanDefinition
上面说过 postProcessBeforeInstantiation 方法返回 null 的话会继续执行doCreateBean方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// ************重点代码********applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}...populateBean(beanName, mbd, instanceWrapper);...
在 doCreateBean 方法中,会调用调用applyMergedBeanDefinitionPostProcessors方法:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof MergedBeanDefinitionPostProcessor) {MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}
MergedBeanDefinitionPostProcessor接口上面提到到的,AutowiredAnnotationBeanPostProcessor 实现了这个接口所以直接进入到AutowiredAnnotationBeanPostProcessor中的 postProcessMergedBeanDefinition方法:
@Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {// 寻找需要注入的字段或方法,并封装成 InjectionMetadata// 就是利用反射遍历类的所有字段和方法,找到标注了@Resource 注解的,并缓存InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);// 检查元数据中的注解信息metadata.checkConfigMembers(beanDefinition);}
InjectionMetadata 就是注入的元信息描述,主要字段如下
InjectedElement 就是注入的元素,主要字段如下:
查找注入元数据
接着继续进入到findAutowiringMetadata,findAutowiringMetadata会调用buildAutowiringMetadata方法创建注入元数据,然后将元数据缓存到injectionMetadataCache属性中:
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为null或者metadata中存储的targetClass和当前clazz不等if (InjectionMetadata.needsRefresh(metadata, clazz)) {// 这里相当于是一个double check,防止多线程出现的并发问题synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {...// 构建注入元信息,见下文详解metadata = buildAutowiringMetadata(clazz);// 放入缓存中this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;}
创建需要注入的元信息AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {// 用于判断某个类是否可能 被标记指定的某个注解if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}
// 用于判断某个类是否可能 被标记指定的某个注解public static boolean isCandidateClass(Class<?> clazz, Class<? extends Annotation> annotationType) {return isCandidateClass(clazz, annotationType.getName());}public static boolean isCandidateClass(Class<?> clazz, String annotationName) {// 如果注解所在包是java开头,任何类上都可能标记这个注解// Java开头的注解包就是JDK自带的注解,任何类都可能标记.这个时候返回True就没什么问题if (annotationName.startsWith("java.")) {return true;}// 注解所在包不是java开头的情况// 可以认为是自定义注解,例如Spring的@Service @Autowired @Value 对Spring来说就是其自定义注解// 如果类的包是以java开头,则不可能标记自定义的注解if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {return false;}return true;}// 这里的class就是自己的class类。如果类的包是以java开头,则不可能标记自定义的注解// 如果类的包不是以java开头static boolean hasPlainJavaAnnotationsOnly(Class<?> type) {return (type.getName().startsWith("java.") || type == Ordered.class);}
