从零开始造Spring06---实现spring注解-2

举报
码农飞哥 发表于 2021/05/29 13:47:51 2021/05/29
【摘要】 前言 接上一篇《从零开始造Spring05—实现spring注解-1》,今天我们接着学习spring注解。这是学习刘欣老师《从零开始造Spring》课程的学习笔记。上一篇我们实现了Bean的生成,这一篇我们将接着来实现Bean的注入,也叫依赖注入。 具体实现 数据结构 注: @Autowired 应用的地方有多处,此处我们只实现了应用于Field上。Me...

前言

接上一篇《从零开始造Spring05—实现spring注解-1》,今天我们接着学习spring注解。这是学习刘欣老师《从零开始造Spring》课程的学习笔记。上一篇我们实现了Bean的生成,这一篇我们将接着来实现Bean的注入,也叫依赖注入。
这里写图片描述

具体实现

数据结构

这里写图片描述
注: @Autowired 应用的地方有多处,此处我们只实现了应用于Field上。Member对象来自于java.lang.reflect 包,其相当于FieldMethodConstructor的子类。
关键代码
InjectionMetadata

public class InjectionMetadata { private final Class<?> targetClass; private List<InjectionElement> injectionElementList; public InjectionMetadata(Class<?> targetClass, List<InjectionElement> injectionElementList) { this.targetClass = targetClass; this.injectionElementList = injectionElementList; } public List<InjectionElement> getInjectionElementList() { return injectionElementList; } /** * 核心的inject,在Bean生命周期的postProcessPropertyValues方法中被调用 * @param target */ public void inject(Object target) { if (injectionElementList == null || injectionElementList.isEmpty()) { return; } for (InjectionElement ele : injectionElementList) { ele.inject(target); } }
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

AutowiredFieldElement

public class AutowiredFieldElement extends InjectionElement { boolean required; public AutowiredFieldElement(Field f, boolean required, AutowireCapableBeanFactory factory) { super(f,factory); this.required = required; } public Field getField() { return (Field) this.member; } @Override public void inject(Object target) { Field field = this.getField(); try { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); //获取Bean的实例 Object value = factory.resolveDependency(desc); if (value != null) { //将field 置于可访问的 ReflectionUtils.makeAccessible(field); // 将被依赖的Bean注入到依赖的Bean中 field.set(target, value); } } catch (Throwable ex) { throw new BeanCreationException("Could not autowire field: " + field, ex); } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

DependencyDescriptor 类是用来描述依赖的。相关类图如下:
这里写图片描述
这里扩展AutowireCapableBeanFactory 新接口主要是为了将resolveDependency方法隐藏于Spring内部,因为BeanFactory 主要是面向使用Spring的程序员。resolveDependency方法于他们没有实际用途。
关键代码:DefaultBeanFactory

@Override public Object resolveDependency(DependencyDescriptor descriptor) { Class<?> typeToMatch = descriptor.getDepencyType(); for (BeanDefinition bd : this.beanDefinitionMap.values()) { //确保BeanDefinition 有class对象 resolveBeanClass(bd); Class<?> beanClass = bd.getBeanClass(); if (typeToMatch.isAssignableFrom(beanClass)) { return getBean(bd.getID()); } } return null; } public void resolveBeanClass(BeanDefinition bd) { if (bd.hasBeanClass()) { return; } else { try { bd.resolveBeanClass(this.getBeanClassLoader()); } catch (ClassNotFoundException e) { throw new RuntimeException("can't load class:"+bd.getBeanClassName()); } } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Bean的生命周期

Bean的生命周期共有四个阶段:
这里写图片描述
在此处我们只关注Bean的实例化和初始化阶段。
这里写图片描述
关键代码:AutowiredAnnotationProcessor

 @Override public void postProcessPropertyValues(Object bean, String beanName) throws BeansException { InjectionMetadata metadata = buildAutowiringMetadata(bean.getClass()); try { metadata.inject(bean); } catch (Exception ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } } public InjectionMetadata buildAutowiringMetadata(Class<?> clazz) { LinkedList<InjectionElement> elements = new LinkedList<InjectionElement>(); Class<?> targetClass = clazz; LinkedList<InjectionElement> currentElements = new LinkedList<InjectionElement>(); for (Field field : targetClass.getDeclaredFields()) { Annotation ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { continue; } boolean required = determineRequiredStatus(ann); currentElements.add(new AutowiredFieldElement(field, required, beanFactory)); } } for (Method method : targetClass.getDeclaredMethods()) { //TODO 处理方法注入 } elements.addAll(0, currentElements); targetClass = targetClass.getSuperclass(); while (targetClass != null && targetClass != Object.class) ; return new InjectionMetadata(clazz, elements); }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

那么怎么使用这些PostProcessor呢?
1. 创建PostProcessor

 public AbstractApplicationContext(String configFile) { factory = new DefaultBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); Resource resource = getResourceByPath(configFile); reader.loadBeanDefinitions(resource); factory.setBeanClassLoader(this.getBeanClassLoader()); registerBeanPostProcessors(factory); }
 protected void registerBeanPostProcessors(ConfigurableBeanFactory beanFactory) { AutowiredAnnotationProcessor postProcessor = new AutowiredAnnotationProcessor(); postProcessor.setBeanFactory(beanFactory); beanFactory.addBeanPostProcessor(postProcessor); }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. 加到BeanFactory
    ConfigurableBeanFactory上加入

  2. DefaultBeanFactory. populateBean()调用
    DefaultBeanFactory 类实现了ConfigurableBeanFactory 接口

 protected void populateBean(BeanDefinition bd, Object bean) { for (BeanPostProcessor processor : this.getBeanPostProcessors()) { if (processor instanceof InstantiationAwareBeanPostProcessor) { ((InstantiationAwareBeanPostProcessor)processor).postProcessPropertyValues(bean, bd.getID()); } } ..... }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

源码地址

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/82315766

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。