首页 > 其他分享 >Spring中的字段注入是如何实现的

Spring中的字段注入是如何实现的

时间:2023-06-10 13:56:20浏览次数:32  
标签:Spring Object 如何 Bean 注解 注入 属性

spring中属性的注入方式

Spring中属性注入的方式包括以下几种:

  1. Setter 方法注入:通过在 Bean 类中定义对应的属性setter方法,然后在 XML 配置文件或 Java 配置类中使用 或 @Value 注解来为这些属性设置数值。

  2. 构造函数注入:通过在 Bean 的构造函数中定义对应的参数来实现。在 XML 配置文件或 Java 配置类中使用 元素或 @Autowired 注解来指定参数的值。

  3. 字段注入:通过在 Bean 类中添加对应的字段,并添加 @Autowired 或 @Resource 等注解,让 Spring 自动将需要的依赖注入到该字段中。

  4. 接口回调注入:通过实现一个特定的接口,如 ApplicationContextAware 接口、BeanNameAware 接口等,并重写该接口中的对应方法,使得 Spring 在创建 Bean 时调用这些方法来完成依赖注入。

除了以上四种方式外,还可以通过自定义注入器来实现属性注入,用户可以自定义一个 Injector 实现类,并在 XML 配置文件或 Java 配置类中注册该实现类,以实现更加灵活的注入方式。

总的来说,Spring 中的属性注入主要就是通过 Bean 容器来管理各个 Bean 对象之间的依赖关系,而 Spring 提供的各种注入方式,都是为了提供更加灵活、方便地实现属性注入,以满足不同场景下的需求。

字段注入的原理

Spring 中的字段注入会使用到 Java 反射技术。

具体来说,在 Spring 对象创建时,会先通过构造函数或工厂方法等方式实例化 Bean 对象,然后再进行属性注入。对于字段注入,Spring 内部维护了一个 AutowiredAnnotationBeanPostProcessor 后置处理器,在对象创建完成后,会检查 Bean 中标记了 @Autowired 或 @Resource 注解的字段,并根据字段类型和名称在容器中寻找匹配的 Bean 对象,最终通过反射将依赖注入到对应的字段中。

下面是字段注入的具体源码实现:

public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
    // ...

    @Nullable
    private Object autowiredProperty(
            String beanName, Object bean, PropertyDescriptor pd, @Nullable Object propertyValue) {

        // 获取当前属性的注解信息
        Method writeMethod = pd.getWriteMethod();
        Annotation[] annotations = bridge.getAnnotations(writeMethod);
        for (Annotation ann : annotations) {
            if (ann instanceof Autowired) {
                // 如果是 @Autowired 注解,则从容器中查找并注入依赖
                Object value = autowireByType(
                        beanName, bean, pd.getPropertyType(), pd.getName(), ann);
                if (value != null) {
                    propertyValue = value;
                }
            }

            else if (ann instanceof Inject) {
                // ...
            }

            else if (ann instanceof Value) {
                // ...
            }
        }

        return propertyValue;
    }

    @Nullable
    protected Object autowireByType(
            String beanName, Object bean, Class<?> type, String fieldName, @Nullable Annotation autowiredAnnotation) {

        // 获取 AutowireCapableBeanFactory 对象
        AutowireCapableBeanFactory factory = getAutowiredCapableBeanFactory();

        // 根据类型和名称在容器中查找 Bean 对象
        Object res = null;
        if (factory != null) {
            DependencyDescriptor desc = new AutowireUtils.TypeDependencyDescriptor(
                    type, autowiredAnnotation, true, getNonSelfDeclaredPropertiesOnly());
            res = factory.resolveDependency(desc, beanName, null, null);
        }
        return res;
    }

    // ...
}

在上述代码中,autowiredProperty 方法用于注入单个属性值,并依次遍历该属性上的各种注解信息。当检测到 @Autowired 注解时,则调用 autowireByType 方法对该属性进行自动装配。在 autowireByType 方法中,会调用 AutowireCapableBeanFactory 的 resolveDependency 方法,通过 type 和名称等信息在 Spring 容器中查找匹配的 Bean 对象,并返回对象实例。

总的来说,Spring 中的字段注入使用 Java 反射技术实现,可以更加灵活地管理对象之间的依赖关系。当然,反射也可能导致性能瓶颈,在实际开发中需要适度使用,并结合其他技术手段对其进行优化。

标签:Spring,Object,如何,Bean,注解,注入,属性
From: https://www.cnblogs.com/hardyzhou/p/17471183.html

相关文章

  • SQL注入(Low)
    首先判断是否可以注入输入:’发现网站报错了,表示可以注入(后台有进行执行)在判断是为字符型还是数字型输入:1and1=1再输入:1and1=2因为1=1为真,1=2为假,但是1=2还是有回显输入:1‘and1=1#  (#号和--一样注释掉后面部分)--后有空格再输入:1’and1=2#没有回显所以表示这个是字......
  • SQL注入
    一、寻找注入点这一部分其实对于我这种刚学基础的小白是最难的,很长一段时间就在盲目的换网站,测试,扫描,不行就换下一个,我推荐大家使用googlehacking,其实就是高级搜索语言,我总结几个最简单最常用的用法intext:寻找正文中含有关键字的网页例如:intext:后台登录将只返回......
  • Failed to bind properties under 'spring.datasource.primary' to javax.sql.DataSou
     2023-06-1011:04:13.778WARN22452---[main]ConfigServletWebServerApplicationContext:Exceptionencounteredduringcontextinitialization-cancellingrefreshattempt:org.springframework.beans.factory.UnsatisfiedDependencyException:Error......
  • Failed to bind properties under 'spring.datasource.primary' to javax.sql.DataSou
     2023-06-1011:04:13.778WARN22452---[main]ConfigServletWebServerApplicationContext:Exceptionencounteredduringcontextinitialization-cancellingrefreshattempt:org.springframework.beans.factory.UnsatisfiedDependencyException:Error......
  • 蛋白质是如何生成的
    蛋白质的生成过程称为蛋白质合成或蛋白质生物合成,它发生在细胞内的核糖体中。蛋白质合成包括两个主要的步骤:转录和翻译。转录(Transcription):转录是指将DNA中的基因信息转录成RNA的过程。在细胞核中,DNA的两条链解开,其中一条链作为模板,由RNA聚合酶酶依据碱基配对原则合成与DNA模......
  • Failed to bind properties under 'spring.datasource.primary' to javax.sql.DataSou
    ​  2023-06-1011:04:13.778WARN22452---[main]ConfigServletWebServerApplicationContext:Exceptionencounteredduringcontextinitialization-cancellingrefreshattempt:org.springframework.beans.factory.UnsatisfiedDependencyException:......
  • Failed to bind properties under 'spring.datasource.primary' to javax.sql.DataSou
    ​  2023-06-1011:04:13.778WARN22452---[main]ConfigServletWebServerApplicationContext:Exceptionencounteredduringcontextinitialization-cancellingrefreshattempt:org.springframework.beans.factory.UnsatisfiedDependencyException:......
  • EXCEL如何实现输入指定ID查询对应的信息
    要求:在第2行输入ID按enter键后查询出第4行的信息。步骤:(1)首先将第2行单元格的属性【保护】中取消【锁定】,因为在要在此行输入需要查询的ID,在锁定工作表的情况下,要保障此行是可写的。(备注:第2行需调整为文本格式) (2)本次的实验数据只有三个条目(ID:0201,0202,0203)将这三行数据放在工......
  • 如何提取DNA【原理】
    DNA提取是一种将DNA从生物样本中分离和纯化的过程。下面是一般的DNA提取步骤:选择样本:选择包含DNA的样本,可以是细胞、组织、血液、唾液、植物材料等。细胞破碎:使用物理或化学方法将细胞破碎,以释放DNA。常见的方法包括机械破碎、冻融、酶解或化学溶解。溶解蛋白质:加入蛋白......
  • 回答朋友提问:Fiori UI 中如何知道当前系统 Client ID (一)
    今天我的SAP开发技术交流群里,有朋友问这样的问题:在Fiori界面中,怎么查看当前Client?我觉得要回答这个问题,需要提问的朋友提供更多的背景信息,比如:Fiori界面,是运行在ABAPOn-Premises上,还是Cloud环境(Cloud环境下想知道ClientID貌似没有意义,因为这个字段值只对SAP......