Spring框架概述 --- 控制反转, 依赖注入, 容器和Bean

2023-11-15

Spring框架的好处

  • 轻量: Sprinh是轻量的, 基础版本大约2MB
  • 控制反转: Spring 通过控制反转实现了松散耦合
  • AOP: Spring支持面向切面的编程
  • MVC容器: Spring的Web框架
  • 事务管理: Spring提供一个持续的事务管理接口, 可以拓展到上至本地事务下至全局事务
  • 异常处理: Spring提供方便的API把具体技术的相关异常转化为一致的unchecked异常

控制反转

  • 一种设计思想,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制
  • 具体来说: 在传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;
  • 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;
    因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了

Spring IOC容器和Bean

  • Bean是Spring管理的基本单位,在基于Spring的Java EE应用中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。在Spring中,Bean的是一个非常广义的概念,任何的Java对象、Java组件都被当成Bean处理。
  • Spring框架的核心是Spring IOC容器. 容器创建对象, 将它们装配在一起, 配置它们并管理生命周期.

BeanFactory

  • BeanFactory是ApplicationContext 的父类, BeanFactory实际上可以说是Spring的核心容器
  • 这是一个用来访问 Spring 容器的 root 接口,要访问 Spring 容器,我们将使用 Spring 依赖注入功能,使用 BeanFactory 接口和它的子接口。
  • 通常情况,BeanFactory 的实现是使用懒加载的方式,这意味着 beans 只有在我们通过 getBean() 方法直接调用它们时才进行实例化。

ApplicationContext

  • ApplicationContext 是 Spring 应用程序中的中央接口,用于向应用程序提供配置信息。它继承了 BeanFactory 接口,所以 ApplicationContext 包含 BeanFactory 的所有功能以及更多功能!它的主要功能是支持大型的业务应用的创建。
  • 与 BeanFactory 懒加载的方式不同,它是预加载,所以,每一个 bean 都在 ApplicationContext 启动之后实例化。

Bean的作用域

  • singleton: 单例模式, 在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
  • protoype: 原型模式, 每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
  • request: 对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
  • session: 对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
  • globalseesion: 每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

在Spring中设置bean的作用域

  • 采用XML配置方式时,可以用标签中的scope属性可以指定bean的作用范围
<bean id="ajaxGetWarningDataAction" class="com.mln.pems.collect.actions.AjaxGetWarningDataAction" scope="prototype">
	<property name="daoSrv" ref="daoSrv" />
	<property name="emRunSrv" ref="emRunSrv" />
</bean>
  • 采用注解方式时,可以用@Scope(value = “singleton”)来指定
@Scope(value = “prototype”) 
public class AccountServiceImpl implements AccountService {
	......
}

依赖注入 — 控制反转的实现方法

  • Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中

依赖注入的三种方式 — 以下使用注解@Autowire的装配方法

  • 属性注入 – Attributed-based DI
@Service
public class BService {
	@Autowired
	AService aService;
}
  • setter注入 – setter-based DI
@Service
public class BService {
	AService aService;
	@Autowired
	public void setaService(AService aService) {
		this.aService = asService;
	}
}
  • 构造方法注入 – constructor-based DI
@Service
public class BService {
	AService aService;
	@Autowired
	public BService(AService aService) {
		this.aService = asService;
	}
}

setter注入和构造器注入的区别

  • 部分依赖:假设一个类中有3个属性,有一个有三个arg的构造函数和三个setter方法。在这种情况下,如果您只想传递一个属性的信息,则只能通过setter方法
  • 覆盖:Setter注入会覆盖构造函数注入。如果我们同时使用构造函数和setter注入,IOC容器将使用setter注入。
  • 变化:我们可以通过二次注射轻松更改值。它不会像构造函数一样创建新的bean实例。因此,setter注入比构造函数注入更灵活。

推荐使用构造器注入

  • 依赖不可变:这个好理解,通过构造方法注入依赖,在对象创建的时候就要注入依赖,一旦对象创建成功,以后就只能使用注入的依赖而无法修改了,这就是依赖不可变(通过 set 方法注入将来还能通过 set 方法修改)。
  • 依赖不为空:通过构造方法注入的时候,会自动检查注入的对象是否为空,如果为空,则注入失败;如果不为空,才会注入成功。
  • 完全初始化:由于获取到了依赖对象(这个依赖对象是初始化之后的),并且调用了要初始化组件的构造方法,因此最终拿到的就是完全初始化的对象了。

Spring中bean的装配 ---- 定义bean并描述bean之间的依赖关系

基于XML形式的手动装配

  • 手动装配,通常在XML配置文件中实现
//创建实体类: People
package com.lisi.pojo;
 
public class People {
    
    private Cat cat;
    private Dog dog;
    private String name;
	....
	....
}
手动装配
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 
   <bean id="dog" class="com.lisi.pojo.Dog"/>
   <bean id="cat" class="com.lisi.pojo.Cat"/>
 
   <bean id="people" class="com.lisi.pojo.People">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="name" value="haha"/>
   </bean>
</beans>

基于XML形式的自动装配

//创建实体类: People
package com.lisi.pojo;
 
public class People {
    
    private Cat cat;
    private Dog dog;
    private String name;
	....
	....
}
  • byName: bean的id与属性名,一致则能赋值
<bean id="cat" class="com.lisi.pojo.Cat"></bean>
<bean id="dog" class="com.lisi.pojo.Dog"></bean>
<bean id="people" class="com.lisi.pojo.People" autowire="byName"></bean>
  • byType: 根据类型判断是否能装配,
  • spring容器中bean的类型为兼容性的属性赋值, 兼容性:父类与实现的接口可以
  • 使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常
  • 也就是不能再加入 <bean id="cat1" class="com.lisi.pojo.Cat"></bean>, 这样有两个Cat对象
<bean id="cat" class="com.lisi.pojo.Cat"></bean>
<bean id="dog" class="com.lisi.pojo.Dog"></bean>
<bean id="people" class="com.lisi.pojo.People" autowire="byType"></bean>

基于注解形式的自动装配

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean

  • @Component:
  • 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等. 使用时只需将该注解标注在相应类上即可。
  • @Repository: 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Service: 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Controller : 该注解通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同

可以通过以下注解将定义好 Bean 装配到其它的 Bean 中

  • @Autowired:
  • 可以应用到 Bean 的属性变量、setter 方法、非 setter 方法及构造函数等,默认按照 Bean 的类型进行装配
  • @Autowired 注解默认按照 Bean 的类型进行装配,默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合 @Qualifier 注解一起使用
  • @Resource:
  • 作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 的名称进行装配。
  • @Resource 中有两个重要属性:name 和 type。
    Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。
    如果指定 name 属性,则按实例名称进行装配;
    如果指定 type 属性,则按 Bean 类型进行装配;
    如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
  • @Qualifier 与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
@Service
public class CategoryService {

    private static final Logger LOG = LoggerFactory.getLogger(CategoryService.class);

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private SnowFlake snowFlake;
    .....
    .....
	.....

基于Java配置类的装配

  • 不使用xml文件配置Bean,而是单独写一个配置类来配置Bean
  • @Bean 注解扮演与 元素相同的角色。用到方法上,表示当前方法的返回值是一个bean
  • @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 Bean 间依赖关系。相当于spring的配置文件XML
@Configuration
public class ServiceConfiguration {
	 @Bean
	 public InventoryService inventoryService() {
	 	return new InventoryService();
	 }
	 @Bean
	 public ProductService productService() {
	 	return new ProductService(inventoryService());
	 }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring框架概述 --- 控制反转, 依赖注入, 容器和Bean 的相关文章

随机推荐

  • nodejs知识系列:npm查询包的所有版本及安装指定版本

    说明 在添加依赖或者安装本地环境时 有时候不支持最新的安装包 需要自己指定版本号 博主最近在win7开发nestjs和angular经常遇到 解决方案 npm view 目标包名 versions json或cnpm view 目标包名 v
  • python矩阵交换两行_Python 实现交换矩阵的行示例

    Python 实现交换矩阵的行示例 如下所示 TODO r1 r2 直接修改参数矩阵 无返回值 def swapRows M r1 r2 M r1 M r2 M r2 M r1 pass 以上这篇Python 实现交换矩阵的行示例就是小编分
  • 人工智能-统计机器学习- 自适应提升算法

    监督学习 Boosting adaptive boosting 自适应提升 对于一个复杂的分类任务 可以将其分解为 若干子任务 然后将若干子任务完成方法综合 最终完成该复杂任务 我们将这若干子任务称为弱分类器 weak classifier
  • 敏捷子弹(摘自《代码之道》第二章)

    最近面试了几家公司 感觉大家对采纳Scrum流程还是挺感兴趣的 5年前 我翻译了 代码之道 这本书 其中 第二章有一篇文章谈到了敏捷方法 文章的后半部分还对Scrum做了重点介绍 作者原是微软员工 他的一些观点和建议难免会结合微软公司的实践
  • 二分查找模板

    二分查找模板 基础模板 适用于查找某个在数组中的数的位置 def searchInsert self nums List int target int gt int n len nums l 0 注意1 r n 1 注意2 while l
  • JS_socket.io简单使用

    安装socket io npm install save socket io demo目录 index js node modules package json views index html 服务端代码 index js const h
  • Solidity 合约安全,常见漏洞(第三篇)

    Solidity 合约安全 常见漏洞 第三篇 ERC20 代币问题 如果你只处理受信任的 ERC20 代币 这些问题大多不适用 然而 当与任意的或部分不受信任的 ERC20 代币交互时 就有一些需要注意的地方 ERC20 转账扣费 当与不信
  • 建模杂谈系列231 对象化-学习型对象

    说明 简单归纳一下最近的学习型对象封装 做一个基类 之后可以基于这个基类继续迭代 内容 1 关于字典的格式 Python的字典格式写起来太麻烦了 所以我定义了一个简单对象 来取代字典 字典的赋值方式 a dict a dict abc 1
  • 为什么 Linux 没有注册表?

    目录 linux无注册表机制的优势 为什么 Linux 没有注册表 linux无注册表机制的优势 linux系统有注册表吗 鸿网互联 本教程操作环境 linux7 3系统 Dell G3电脑 linux系统没有注册表 注册表 Registr
  • MySql 插入(insert)性能测试 以及优化

    http blog csdn net lgh1117 article details 8619486 测试环境 笔记本电脑 CPU I5 系统 MAC OS 10 7 内存 8G 硬盘 5400转 笔记本硬盘 MySql 版本 Oracle
  • ChatGLM(国内版的chatGPT)

    Git链接 GitHub THUDM ChatGLM 6B ChatGLM 6B 开源双语对话语言模型 An Open Bilingual Dialogue Language Model 介绍 ChatGLM 6B 是一个开源的 支持中英双
  • Unity UI拖拽模型选择

    指定一块区域 玩家鼠标or手指拖拽这个区域 模型会进行偏移 并用于进行人物 道具的选择 给模型定义一些属性 using System Collections using System Collections Generic using Un
  • BaGet搭建Nuget私仓(window10&docker)

    文章目录 一 搭建背景 二 框架简介 三 私仓搭建 1 环境 2 win10上部署 2 1安装SDK 2 2下载和解压BaGet包 2 3运行项目 2 4类库项目 2 5将包发布到私有Nuget中 2 6使用BaGetFirstLib 2
  • React中使用Hooks - useImperativeHandle

    useImperativeHandle useImperativeHandle ref createHandle dependencies 可以使用 useImperativeHandle 来暴露一些特定的操作 在子组件中使用useImpe
  • 随机森林和梯度提升回归树(笔记)

    最近在自学图灵教材 Python机器学习基础教程 在csdn以博客的形式做些笔记 决策树集成 集成 ensemble 是合并多个机器学习模型来构建更强大模型的方法 在机器学习文献中有许多模型都属于这一类 但已证明有两种集成模型对大量分类和回
  • com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@解决方案

    在配置c3p0通过配置文件创建数据源对象时 报错信息如题 原因一 你的数据库各类信息是否正确 url username password是否正确 原因二 是否将必需的jar包都放进工程中 原因三 你导入的mysql的jar包和你设置的驱动信
  • chrome浏览器如何查看、修改、删除Cookie

    1 chrome浏览器的cookie保存位置 C Users 你的用户名 AppData Local Google Chrome User Data Default 快捷键win r 运行以上路径可以打开该目录 Cookies文件存储的就是
  • centos手动增加删除swap分区

    SWAP是Linux中的虚拟内存 用于扩充物理内存不足而用来存储临时数据存在的 它类似于Windows中的虚拟内存 在Windows中 只可以使用文件来当作虚拟内存 而linux可以文件或者分区来当作虚拟内存 首先查看当前的内存和swap
  • shell浅谈之八I/O重定向

    一 简介 I O重定向用于捕获一个文件 命令 程序或脚本甚至代码块的输出 然后把捕获到的输出作为输入发送给另外一个文件 命令 程序或脚本等 I O重定向最常用的方法是管道 管道符 二 详解 1 管道 1 管道技术是Linux间的一种通信技术
  • Spring框架概述 --- 控制反转, 依赖注入, 容器和Bean

    Spring框架概述 控制反转 依赖注入 容器和Bean Spring框架的好处 控制反转 Spring IOC容器和Bean 依赖注入 控制反转的实现方法 Spring中bean的装配 定义bean并描述bean之间的依赖关系 Sprin