怎样做违法网站,加盟网络营销推广公司,广东公共广告20120708,旅游网站的建设的文献综述前置知识
1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory
注入处理
我们可以看到接口AutowireCapableBeanFactory中有两个方法。 第一个是单个注入#xff1a;
Null…前置知识
1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory
注入处理
我们可以看到接口AutowireCapableBeanFactory中有两个方法。 第一个是单个注入
Nullable
Object resolveDependency(DependencyDescriptor descriptor, Nullable String requestingBeanName) throws BeansException;
还有一个是Set集合注入
Nullable
Object resolveDependency(DependencyDescriptor descriptor, Nullable String requestingBeanName,
Nullable SetString autowiredBeanNames, Nullable TypeConverter typeConverter) throws BeansException;我们可以看到它的实现关系
下面这个代码从IOC中查找并注入一个Bean依据这个区跟踪一下源码
public class AnnotationDependencyInjectResolutionDemo {Autowiredprivate Person person;public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext();context.register(AnnotationDependencyInjectResolutionDemo.class);context.refresh();QualifierAnnotationDependencyInjectDemo bean context.getBean(QualifierAnnotationDependencyInjectDemo.class);}}我们直接断点看一下DefaultListableBeanFactory#resolveDependency
DependencyDescriptor参数里面的信息 DependencyDescriptor 描述了我们要注入的目标的一些信息 参考文章:https://blog.csdn.net/andy_zhang2007/article/details/88135669
// 保存所包装依赖(成员属性或者成员方法的某个参数)所在的声明类
// 其实该信息在 field/methodParameter 中已经隐含
private final Class? declaringClass;
// 如果所包装依赖是成员方法的某个参数则这里记录该成员方法的名称
Nullable
private String methodName;
// 如果所包装的是成员方法的某个参数则这里记录该参数的类型
Nullable
private Class?[] parameterTypes;
// 如果所包装的是成员方法的某个参数则这里记录该参数在该函数参数列表中的索引
private int parameterIndex;
//如果所包装的是成员属性则这里记录该成员属性的名称
Nullable
private String fieldName;
// 标识所包装依赖是否必要依赖
private final boolean required;
// 标识所包装依赖是否需要饥饿加载
private final boolean eager;
// 标识所包装依赖的嵌套级别
private int nestingLevel 1;
// 标识所包装依赖的包含者类通常和声明类是同一个
Nullable
private Class? containingClass;
// 所包装依赖 ResolvableType 的缓存
Nullable
private transient volatile ResolvableType resolvableType;
// 所包装依赖 TypeDescriptor 的缓存
Nullable
private transient volatile TypeDescriptor typeDescriptor;下面分类去跟踪注入过程。
依赖查处理过程
1 普通的字段
Configuration
public class LookUpByAnnotationSingle {AutowiredPersonHolder personHolder;SingleBeanPersonHolder personHolder(){Person person new Person();person.setId(777L);person.setName(yong);return new PersonHolder(person);}public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext();context.register(LookUpByAnnotationSingle.class);context.refresh();Object bean context.getBean(personHolder);context.close();}
}字段注入前面的判断都会跳过进入到下面这个方法 同样的我们只关注字段注入的核心流程前面的条件都不满足来到这个方法findAutowireCandidates 这个方法里面首先BeanFactoryUtils#beanNamesForTypeIncludingAncestors找到候选的Beans 候选的Bean是通过上面这个方法找到的并且返回的时候将Bean对象放入到Map中。 然后我们如果我们多个bean,determineAutowireCandidate这个方法会决定一个Bean决定的方式为如果使用了Primary就注入PrimaryBean否则Ordered根据这个接口定义或者我们在Bean申明的时候标注了Order注解的优先级来寻找数字越低优先级越高 2 集合
Autowired
private CollectionPerson personGroupAll;集合注入核心逻辑会走到下面这个方法这个方法返回的时候multipleBeans已经不为空了这个这个直接返回。 为什么上面可以直接返回呢因为在resolveMultipleBeans方法中判断了注入的类型如果是集合类型也是走的一样的逻辑findAutowireCandidates找到候选的Bean进行返回。 3 懒加载
Autowired
Lazy
private Person person;在懒注入的时候我们在这个方法已经有值了所以逻辑在这一步就结束了返回的是一个代理对象。 这个对象是cglib提升后的对象
4 Optional
Autowiredprivate OptionalPerson person;核心逻辑是走下面 其实里面的逻辑是一样的只是最后封装为Optional:
Autowired注入过程
元信息解析依赖查找依赖注入字段方法 核心方法是AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement#inject在注入的过程中会先去处理依赖也就是上面的流程 参数bean是我们标注的类
这个方法被谁调用呢属性后置处理AutowiredAnnotationBeanPostProcessor#postProcessProperties当我们用xml配置的时候那么这个时候PropertyValues存储的就是的配置值 从打断点来看postProcessProperties方法会先于set注入执行也就是先注入元信息然后再注入值。 下面这个方法是合并子类和父类的元信息每个类都会进入这个方法如果没有父类就是自己的元信息这个方法在postProcessProperties之前执行。 这里会去查找AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata