返回顶部
首页 > 资讯 > 后端开发 > Python >浅谈Spring注入模型
  • 209
分享到

浅谈Spring注入模型

Spring注入模型Spring注入 2023-05-18 08:05:44 209人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录spring注入bean的方式Spring的注入模型代码示例定义bean对象定义配置类定义后置处理器定义测试方法自动注入和手动注入Spring注入bean的方式 DI exist

Spring注入bean的方式

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.

从Spring的官网中可以得知,Spring注入bean的方式由两种,一种是通过构造方法进行注入,另外一种是通过setter方法进行注入。
但熟悉Spring开发的同学在实际的开发中经常使用的注入方式是通过@Autowired以及@Resource的方式来注入bean的。那么通过注解的方式注入是跟上面两种注入方式是一样的吗?在研究这个问题之前,我们需要来了解Spring的注入模型。

Spring的注入模型

如果不深入到Spring的源码,是很少有机会了解到Spring的注入模型(AutowireMode)。但是为了扫清我们学习Spring源码的障碍,我们有必要了解下Spring的注入模型。
Spring的注入模型有四种,分别是:

  • autowire_no(0):默认的注入模型,如果在beanA中注入beanB,如果没有提供注解或者xml的注入方式,beanB是无法注入到beanA中的。
  • autowire_name(1):通过set方法注入,并且set的参数名必须和注入的bean名称一样,在xml中是通过byName
  • autowire_type(2):通过set方法注入,set的参数名可以随意命名,但是类型必须和注入的bean的类型一样,在xml中是通过byType的方式配置
  • autowire_constructor(3):通过构造器注入

代码示例

多说无益,我们直接上代码来加深对这一概念的了解。

定义bean对象

我们简单定义两个类,分别是Student和Address,并且将他们注入到Spring容器中。
Student.java如下

@Component
@Slf4j
public class Student {

    private Address address;

    public Student(){
        log.info("default constructor...");
    }

    public Student(Address address){
        log.info("constructor inject...{}", address);
        this.address = address;
    }

    public void setAddress(Address address){
        log.info("setter...{}", address);
        this.address = address;
    }

    public void showAddress(){
        this.address.info();
    }
}

Address.java如下

@Component
public class Address {

    public void info(){
        System.out.println("广东省广州市白云区");
    }
}

我们可以看到在Student中有一个属性是Address,并且提供了默认的构造方法以及带参数的构造方法,同时还有一个 set方法。

定义配置类

我们再定义一个config类,用来扫描这两个类所在的包路径,把这两个类注入到Spring容器中。

@ComponentScan("org.example.autoModel.model")
public class MyBeanConfig {
}

定义后置处理器

在Spring中,我们可以在自己定义的后置处理器BeanFactoryPostProcessor,获取到对应的BeanDefinition。
相信大家在学习Spring的时候有了解过BeanDefinition,不熟悉的可以搜索下BeanDefinition的概念,如果阅读过Spring的源码的话,对BeanDefinition应该就更加熟悉了。这里就不做过多的解释了,后面在解读Spring源码的时候应该也会涉及到这部分的知识。
简单的来说,就是一个对象被注入到Spring中,实际是被解析成BeanDefinition对象,里面保存了各种需要用到的信息,并且可以在后置处理器中获取到对应的BeanDefinition对象,然后对其做一些操作。

@Slf4j(topic = "e")
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
//        beanDefinition.setAutowireMode(3);
        log.debug("mode:{}",beanDefinition.getAutowireMode());
    }
}

上面代码所示,我们可以获取这个beanDefinition在Spring容器中对应的autowireMode的值,并且可以修改这个autowireMode的值,来观察下注入模型的改变,对bean的注入方式有什么影响。

定义测试方法

@Test
public void modelTest(){
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
   context.reGISter(MyBeanConfig.class);
   context.register(MyBeanFactoryPostProcessor.class);
   context.refresh();
   Student student = context.getBean(Student.class);
   student.showAddress();
}

执行测试方法,得出如下的结果。

如上面所示,我们可以得到对应的autowireMode的值是0,并且是执行了Student的默认构造方法,由于没有将address属性注入到student中,所在调用address对应的方法的时候,抛出了空指针的异常。
针对上面的对象,我们可以简单分析下:

  • Spring默认的注入模型是0
  • 注入模型是0,意味着执行默认的构造方法,并且不会执行set方法去进行注入address这个对象,所以抛出了空指针异常

我们可以在后置处理器中,修改对应autowioreMode的值,将autowireMode的值修改成1。

beanDefinition.setAutowireMode(1);

然后执行该测试方法,得到下面的结果。

可以看到我们将注入模型的值修改成1,之后,spring就会通过set方法,将address注入到student中,就可以成功调用address的方法了。
当然,我们将注入模型的值修改成2,也是注入成功的,并且也是通过set方法,只不过是byType和byName的区别。这个同学们可以自己尝试下。
下面,我们将注入模型的值修改成3来看下执行的结果。

beanDefinition.setAutowireMode(3);

结果如下:

可以看到,如果将注入模型的值修改成了3,那么Spring是通过带参的构造方法来注入给student的。
通过上面简单的例子,我们就可以了解到注入模型autowireMode对注入方式的影响,这为我们以后阅读Spring的源码打下了基础。

自动注入和手动注入

上面我们将autowireMode值修改成1、2、3,就可以完成属性的自动注入。那如果我们不去修改autowireMode的值,而是使用注解来将属性注入到student中,会是怎样的结果呢?
我们来看下面的代码:

@Component
@Slf4j
public class Student {

    @Autowired
    private Address address;

    public Student(){
        log.info("default constructor...");
    }

    public Student(Address address){
        log.info("constructor inject...{}", address);
        this.address = address;
    }

    public void setAddress(Address address){
        log.info("setter...{}", address);
        this.address = address;
    }

    public void showAddress(){
        this.address.info();
    }
}
@Slf4j(topic = "e")
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
//        beanDefinition.setAutowireMode(3);
        log.debug("mode:{}",beanDefinition.getAutowireMode());
    }
}

查看结果

我们发现使用@Autowired注解注入属性的时候,注入模型的值是0,也就是默认的值。
对于@Autowired的注解,我的看法是,使用注解注入属性是手动注入的方式,Spring提供自动注入的方式只有set方法以及带参的构造方法。而注解的注入方式,只不过是xml手动注入的一种简化,Spring内部处理的机制都是类似的。
了解过xml配置的同学大概有些印象,我们需要指定bean中属性所对应的类的全路径。而使用自动注入,我们可以指定byType或者byName。由于xml方式太久没用了,大概就是这么个意思吧。
所以我认为@Autowired注入的方式,不是自动注入,而是手动注入,只不过Spring容器内部帮我们处理了。当然,关于Spring容器如何处理@Autowired注解的方式注入属性的,同学们可以通过阅读源码来大致了解下。后面大概也会解读下这部分的源码。
以上便是鄙人对Spring注入模型的浅薄认识,如果有错误的话,还请同学们多多包涵。

到此这篇关于浅谈Spring注入模型的文章就介绍到这了,更多相关Spring注入模型内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈Spring注入模型

本文链接: https://lsjlt.com/news/211832.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 浅谈Spring注入模型
    目录Spring注入bean的方式Spring的注入模型代码示例定义bean对象定义配置类定义后置处理器定义测试方法自动注入和手动注入Spring注入bean的方式 DI exist...
    99+
    2023-05-18
    Spring注入模型 Spring注入
  • 浅谈spring DI 依赖注入方式和区别
    目录spring DI 3种DI注解的区别 1 @Autowired 2 @Inject 3 @Resource 3种注入方式的区别 1 field注入 2 构造器注入 3 sett...
    99+
    2024-04-02
  • 浅谈Spring 中 @EnableXXX 注解的套路
    目录前言设计目标@EnableScheduling (导入一个 @Configuration 类)@EnableTransactionManagement(导入一个 ImportSe...
    99+
    2024-04-02
  • 浅谈Python模块导入规范
    模块导入的规范 模块是类或函数的集合,用于实现某个功能。模块的导入和Java 中包的导入的概念很相似都使用import语句。在Python中,如果需要在程序中调用标准库或其他第三方...
    99+
    2024-04-02
  • 浅谈spring aop的五种通知类型
    spring aop通知(advice)分成五类: 前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。 正常返回通知[After returning advice]...
    99+
    2023-05-30
    spring aop 通知
  • 浅谈Python基础之I/O模型
    一、I/O模型 IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。 ...
    99+
    2022-06-04
    浅谈 模型 基础
  • 浅谈Redis的事件驱动模型
    Redis 作为一个 Client-Server 架构的数据库,其源码中少不了用来实现网络通信的部分。而你应该也清楚,通常系统实现网络通信的基本方法是使用Socket编程模型,,包括...
    99+
    2024-04-02
  • 浅谈三种数据库的 SQL 注入
    目录SQL 注入原理SQL 注入分类1. 数字型注入2. 字符型注入3. 其他类型常见数据库的注入SQL ServermysqloracleSQL 注入原理 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程...
    99+
    2022-08-11
    SQL 注入
  • 浅谈SpringBoot @Autowired的两种注入方式
    Autowired有两种注入方式 by type by name 默认使用的是byType的方式向Bean里面注入相应的Bean。例如: @Autowire...
    99+
    2024-04-02
  • 浅谈Node.js:Buffer模块
    Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意。Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该类实现...
    99+
    2022-06-04
    浅谈 模块 js
  • 浅谈怎么给Python添加类型标注
    Python 添加类型标注 Python 如此简洁,书写者在声明变量时甚至无需考虑类型。 但是简洁与复杂间,是存在一个平衡点的。当我们书写较为复杂的项目时,还是希望可以拥有「静态类型...
    99+
    2024-04-02
  • 浅谈为什么#{}可以防止SQL注入
    目录#{} 和 ${} 的区别#{} 底层是如何防止 SQL 注入的?为什么能防止SQL注入?#{} 和 ${} 的区别 #{} 匹配的是一个占位符,相当于 JDBC 中的一个,会对...
    99+
    2024-04-02
  • 浅谈SQL注入的四种防御方法
    最近了解到安全公司的面试中都问到了很多关于SQL注入的一些原理和注入类型的问题,甚至是SQL注入的防御方法。SQL注入真的算是web漏洞中的元老了,著名且危害性极大。下面这里就简单的分享一下我总结的四...
    99+
    2023-09-05
    php web安全
  • 浅谈JavaScript原型链
    目录instanceof 简介Function instanceof Function instanceof 运算符的定义JavaScript 原型继承机制原型与原型链原型继承Obj...
    99+
    2023-05-17
    JavaScript原型 原型链 JavaScript原型链 JavaScript原型
  • 浅谈Python数学建模之数据导入
    目录一、数据导入是所有数模编程的第一步二、在程序中直接向变量赋值2.1、为什么直接赋值?2.2、直接赋值的问题与注意事项三、Pandas 导入数据3.1、Pandas 读取 Excel 文件3.2、Pandas 读取...
    99+
    2022-06-02
    Python 数学建模 Python 数据导入
  • 浅谈@RequestMapping注解的注意点
    目录@RequestMapping注解注意点类上加没加@RequestMappin注解区别@RequestMapping一个坑@RequestMapping注解注意点 类上加没加@R...
    99+
    2024-04-02
  • 浅谈React 的引入
    目录1. CDN 引入1.1 react (先引入)1.2 react-dom (后引入)1.3 查看是否成功引入 react2. Webpack 引入3. create-react...
    99+
    2024-04-02
  • 浅谈Spring Session工作原理
    目录1、引入背景2、使用方法3、工作流程4、缓存机制5、事件订阅6、总结1、引入背景 HTTP协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请...
    99+
    2024-04-02
  • 浅谈一下Spring中的createBean
    目录找到BeanClass并且加载类实例化前实例化Supplier创建对象工厂方法创建对象推断构造方法BeanDefionition 的后置处理实例化后属性填充Aware回调初始化前...
    99+
    2024-04-02
  • 3NF浅谈BI领域的数据模型设计
    目录: 第一部分:基础概念 第二部分:设计方式 第三部分:银行业数据模型基本概念介绍 第四部分:银行业数据模型分主题介绍 第五部分:ODS和EDW 第一部分:基础概念 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作