spring ico容器 spring注入方式 spring与tomcat整合
一、简介
1、什么是spring?
Spring是一个开源的轻量级Java应用开发框架,它提供了一种简单、高效、灵活的方式来构建企业级应用程序。Spring框架的核心特点是依赖注入(Dependency Injection)和面向切面编程(Aspect-Oriented Programming),它通过一组模块化的组件提供全面的支持,使开发人员能够快速搭建可扩展、可维护的应用。
2、目的
学习Spring的目的可以总结为以下几点:
- 简化开发:Spring提供了一系列的工具和抽象,简化了企业级应用开发过程。它通过依赖注入来解决对象间的依赖关系,使得代码更加灵活、可测试和可维护。
- 高效开发:Spring框架提供了诸多模块,如Spring MVC、Spring Boot等,可以快速构建Web应用和微服务。它提供了一种约定优于配置的开发方式,提高了开发效率。
- 提高可扩展性:Spring框架基于接口和模块化设计,能够方便地集成其他开源框架和库。它的松耦合特性使得应用程序更易于扩展和维护。
- 丰富的功能:Spring拥有丰富的功能和特性,包括事务管理、安全性、缓存、消息队列、调度等。它为开发人员提供了一系列解决方案,使得应用程序开发更加便捷。
3、功能及使用范围
Spring的功能范围非常广泛,包括但不限于以下方面:
- 依赖注入和控制反转:通过依赖注入,Spring容器能够将对象之间的依赖关系管理起来,使得对象的创建和使用解耦,提高代码的灵活性和可测试性。
- 面向切面编程:Spring提供了面向切面编程(AOP)的支持,可以将与核心业务逻辑无关的功能(如事务管理、日志记录等)进行横切,提高了代码的重用性和可维护性。
- Web开发支持:Spring提供了Spring MVC模块,用于开发Web应用程序。它能够处理HTTP请求和响应,进行URL路由、数据绑定、表单验证、视图解析等操作,简化了Web开发过程。
- 数据访问支持:Spring框架提供了对各种数据访问技术的支持,包括JDBC、ORM(如Hibernate、MyBatis)、JPA等。它通过抽象出一套统一的数据访问接口,使得数据库访问更加方便和可替换。
- 安全性支持:Spring提供了一套强大的安全性框架,可以进行认证和授权管理。它支持各种身份验证方式,如基于表单的认证、基于角色的访问控制等,保护应用程序的安全性。
总之,Spring框架是Java开发领域最流行的框架之一,它提供了丰富的功能和特性,帮助开发人员构建可靠、高效的企业级应用程序。
一句话概括,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
二、spring IOC
1、ioc的理解
IoC(Inversion of Control,控制反转)是Spring框架的核心概念之一,也是实现依赖注入的基础。它通过解耦对象之间的依赖关系,使得对象的创建和管理由框架来负责,而不是由开发人员手动管理。
在传统的程序设计中,对象之间的依赖关系通常由开发人员在代码中进行硬编码,对象直接通过关键字(如new)来创建和管理。这种方式存在一些问题,如对象之间的耦合度高、可测试性差、扩展性差等。
而IoC则是一种思想上的转变,它将对象的创建和管理权利交给了框架。具体来说,IoC的核心思想是:通过配置或注解,告诉框架需要创建哪些对象,以及对象之间的依赖关系。然后,框架在应用程序运行时根据配置信息动态地创建和组装对象。
Spring通过IoC容器来实现控制反转。IoC容器是一个用于管理对象的容器,它负责创建、组装、初始化和销毁对象。开发人员只需要配置对象的创建和依赖关系,然后通过容器来获取需要的对象即可。
使用Spring的IoC容器,开发人员可以达到以下几个目的:
- 解耦对象之间的依赖关系:通过IoC容器,开发人员只需要关注对象的功能实现,而不需要关心对象是如何创建和组装的。对象之间的依赖关系由容器负责管理,降低了对象之间的耦合度。
- 提高代码的可测试性:由于对象的创建和组装由容器来完成,开发人员可以很容易地对对象进行替换或模拟,从而实现单元测试和集成测试。
- 增强代码的可扩展性:当需要添加新的功能或模块时,只需要配置新的对象和依赖关系,而不需要修改现有的代码。通过配置方式,可以方便地在不影响现有代码的情况下进行扩展。
- 提高代码的灵活性:IoC容器使得对象的创建完全可配置化,可以在运行时根据需要创建不同的实例。同时,框架提供了生命周期管理和依赖解析等功能,使得对象的管理更加便捷。
总而言之,IoC是Spring框架的核心特性之一,它通过控制反转的思想,将对象的创建和依赖关系的管理交给了框架,减少了对象之间的耦合度,提高了代码的可测试性和可扩展性。
2、分析实现
首先创建好我们的maven项目
设置我们的pom.xml
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- 2、导入spring依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><!-- 5.1、junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- 5.2、servlet --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>${javax.servlet.version}</version><scope>provided</scope></dependency>
新建
我们用原来的方式写一下
- 编写一个接口
public interface UserService {public void updUser(); }
- 再编写一个实现类
public class UserServiceImpl1 implements UserService {public void updUser() {System.out.println("修改SQL用户数据"); }
我们原来的方式是这样写的
-
现在我们添加一个实现类
public class UserServiceImpl2 implements UserService {public void updUser() {System.out.println("修改SQL用户数据");//修改用户姓名System.out.println("修改用户姓名");} }
-
当我们测试调方法的时候只需要改动后面的实现类
-
手动实例化的弊端:
1、一旦依赖的接口实现需要大批量改动,迭代,维护成本高
2、当接口的实现类不统一,维护成本更高
我们怎么解决这个问题呢?
3、编写bean
首先我们要在maven项目里面的resources文件里面建立一个基于spring的xml文件
<?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"></beans>
我们在web文件里面建立两个Class类
public class UserAction {private UserService us;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}}
public class GoodsAction {private UserService us;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}}
编写一个测试类
public class demo1 {public static void main(String[] args) { // 加载spring核心配置文件(建模),获取spring的上下文对象,上下文对象中可以获取任何JavaBean对象ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");UserAction userAction = (UserAction) context.getBean("userAction");userAction.updUser();GoodsAction goodsAction = (GoodsAction) context.getBean("goodsAction");goodsAction.updUser();} }
在我们的新建的这个spring-context.xml文件里面添加<bean>
<?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"><!--凡是在spring核心配置文件spring-context.xml中配置,那么该类JavaBean就交给了spring容器管理--><bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/></bean><bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"/></bean><bean class="com.tgq.ioc.service.impl.UserServiceImpl1" id="userService1"/><bean class="com.tgq.ioc.service.impl.UserServiceImpl2" id="userService2"/> </beans>
三、spring IOC的注入方式
spring的ioc有哪些注入方式呢?
- set方法属性注入
- 构造注入
- 接口注入/自动装配
1、set方法属性注入
在我们前面的GoodsAction新添几个属性和get、set方法,一个输出打印的方法toPrint()
public class GoodsAction {private UserService us;private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public List<String> getPeoples() {return peoples;}public void setPeoples(List<String> peoples) {this.peoples = peoples;}private List<String> peoples;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}public void toPrint() {System.out.println(this.name);System.out.println(this.age);System.out.println(this.peoples);}}
在print-context.xml里面设置值,使用set方法属性注入用property
<bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"></property><property name="name" value="旺财"/><property name="age" value="20"/><property name="peoples"><list><value>留守儿童</value><value>情侣</value><value>留守老人</value></list></property></bean>
在测试类里面调用
goodsAction.toPrint();
2、构造注入
在我们的User Action里面添加属性及有参无参的构造方法,一个输出打印的方法toPrint()
public class UserAction {private UserService us;private String name;private int age;private List<String> hobby;public UserAction() {}public UserAction(String name, int age, List<String> hobby) {this.name = name;this.age = age;this.hobby = hobby;}public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}public void toPrint() {System.out.println(this.name);System.out.println(this.age);System.out.println(this.hobby);} }
在print-context.xml里面设置值,使用构造输入需要用constructor-arg标签
<bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/><constructor-arg name="name" value="l"/><constructor-arg name="age" value="18"/><constructor-arg name="hobby"><list><value>唱</value><value>跳</value><value>rap</value></list></constructor-arg></bean>
继续在测试类里面调用toPrint方法
![]()
3、自动装配
自动装配中byName和byType的区别:
byName:在配置好的文件中变量名不更改就不会报错。按照属性的名称进行自动装配。
- 当一个bean的属性名称与其他bean的id匹配时,Spring容器会自动将该bean注入到对应的属性中。
- 如果找不到匹配的bean,则会抛出异常。
- 在XML配置中,可以使用
autowire="byName"
或@Autowired
注解实现byName自动装配。byType:会在整个spring中寻找JavaBean,按照属性的类型进行自动装配。
- 当一个bean的属性的类型与其他bean的class匹配时,Spring容器会自动将该bean注入到对应的属性中。
- 如果有多个匹配的bean,则会抛出异常,需要进行更具体的限定或使用
@Qualifier
注解来解决。- 在XML配置中,可以使用
autowire="byType"
或@Autowired
注解实现byType自动装配。
四、spring与tomcat的整合/spring与web容器的整合
我们的xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"default-autowire="byName"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"><!--凡是在spring核心配置文件spring-context.xml中配置,那么该类JavaBean就交给了spring容器管理--><bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/></bean><bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"/></bean><bean class="com.tgq.ioc.service.impl.UserServiceImpl1" id="userService1"/><bean class="com.tgq.ioc.service.impl.UserServiceImpl2" id="userService2"/> </beans>
编写一个过滤器
@WebListener public class sprintListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("初始化");//spring的上下文ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); //tomcat上下文ServletContext servletContext = sce.getServletContext();servletContext.setAttribute("sprintContext", context);} }
编写servlet类调用它
@WebServlet("userlist") public class Userservlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取到sprint的上下文对象ClassPathXmlApplicationContext Context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("sprintContext");UserService bean = (UserService) Context.getBean("userService1");System.out.println(bean);bean.updUser();} }
启动服务器就完成了整合
相关文章:

spring ico容器 spring注入方式 spring与tomcat整合
一、简介 1、什么是spring? Spring是一个开源的轻量级Java应用开发框架,它提供了一种简单、高效、灵活的方式来构建企业级应用程序。Spring框架的核心特点是依赖注入(Dependency Injection)和面向切面编程(Aspect-Ori…...

ansible 修改远程主机nginx配置文件
安装ansible brew install ansible 或者 pip3 install ansible 添加远程主机 设置秘钥 mac登录远程主机 ssh -p 5700 root192.168.123.211 ssh localhost #设置双机信任 ssh-kyegen -t rsa #设置主机两边的ssh配置文件 vi /etc/ssh/sshd_config/ PermitRootL…...

EV 录屏修复小工具
参考这篇文章, EV录制文件损坏-修复方法, 我用 C# 写了一个小程序. 仓库: github.com/SlimeNull/EvRepair 下载: github.com/SlimeNull/EvRepair/Releases 镜像: gitee.com/slimenull/EvRepair/releases 觉得还不错的话, 点个星星 推荐使用的几个理由: 内嵌 ffmpeg 和 recov…...

蓝牙资讯|中国智能家居前景广阔,蓝牙Mesh照明持续火爆
据俄罗斯卫星通讯社报道,中国已成为全球最大的智能家居消费国,占全球50%—60%的市场份额。未来,随着人工智能技术的发展以及智能家居生态的不断进步,智能家居在中国的渗透率将加速提升。德国斯塔蒂斯塔调查公司数据显示࿰…...

2023年排行前五的大规模语言模型(LLM)
2023年排行前五的大规模语言模型(LLM) 截至2023年,人工智能正在风靡全球。它已经成为热门的讨论话题,吸引了数百万人的关注,不仅限于技术专家和研究人员,还包括来自不同背景的个人。人们对人工智能热情高涨的原因之一是其在人类多…...

DoIP学习笔记系列:(六)满足AES128-CMAC算法的“安全认证”.dll生成实践
文章目录 1. 算法Demo2. 算法实现传送门 DoIP学习笔记系列:导航篇 AES128-CMAC算法在汽车电子控制单元的软件开发中涉及到安全相关的需求经经常用到,具体的算法原理请各位小伙伴自行百度,本篇主要向大家分享该算法如何集成到.dll文件中,在OTA、刷写等场景作为$27服务的安全…...

Collections操作集合的工具类,可变参数、集合操作的工具类
1、可变参数 假设定义一个方法求和,该方法可以灵活的完成如下需求: 计算1个数据的和计算2个数据的和计算3个数据的和计算n个数据的和,甚至可以支持不接收参数进行调用。 1.1、可变参数 可变参数用在形参中可以接收多个数据。可变参数的格式&…...

Linux Kernel:进程表示
环境: Kernel Version:Linux-5.10 ARCH:ARM64 一:前言 Linux内核涉及进程和程序的所有算法都围绕task_struct数据结构建立,具体可看另一篇文章: Linux Kernel:thread_info与task_struct 同时Linux提供了资源限制(resource limit, rlimit)机制,对进程使用系统资源施…...

黑马项目一阶段面试58题 苍穹外卖具体技术细节9题
一、Nginx的作用 1.反向代理 前端把请求发送给nginx,再由nginx将请求发送给后端服务器。 2.负载均衡 提高访问速度;进行负载均衡;保证后端服务安全 二、Swagger有什么作用 直接调试后端请求响应 三、Redis常见数据类型 String、Hash、L…...

SkyEye操作指南:连接TI CCS的IDE调试
现代电力电子控制系统的开发中,DSP芯片以其优越的运算性能在控制算法领域得到越来越广泛的应用。传统的DSP开发过程往往需要在完成控制系统仿真与程序设计后,才能根据比对结果进行程序修改,全过程还需要硬件电路工程师的配合,开发…...

PINN神经网络源代码解析(pyTorch)
参考文献 PINN(Physics-informed Neural Networks)的原理部分可参见https://maziarraissi.github.io/PINNs/ 考虑Burgers方程,如下图所示,初始时刻u符合sin分布,随着时间推移在x0处发生间断. 这是一个经典问题,可使用pytorch通过…...

ChatGPT保密吗?它有哪些潜在风险?如何规避?
自2022年11月公开发布以来,ChatGPT已成为许多企业和个人的必备工具,但随着该技术越来越多地融入我们的日常生活,人们很自然地想知道:ChatGPT是否是保密的。 问:ChatGPT保密吗? 答:否࿰…...

C++中配置OpenCV的教程
首先去OpenCV的官网下载OpenCV安装包,选择合适的平台和版本进行下载,我下载的是Windows的OpenCV-4.7.0版本。OpenCV下载地址 下载好后,解压到自己指定的路径。 配置环境变量: WinR键打开运行窗口,输入sysdm.cpl打开系…...

收银一体化-亿发2023智慧门店新零售营销策略,实现全渠道运营
伴随着互联网电商行业的兴起,以及用户理念的改变,大量用户从线下涌入线上,传统的线下门店人流量急剧收缩,门店升级几乎成为了每一个零售企业的发展之路。智慧门店新零售收银解决方案是针对传统零售企业面临的诸多挑战和问题&#…...

node.js内置模块fs,path,http使用方法
NodeJs中分为两部分 一是V8引擎为了解析和执行JS代码。 二是内置API,让JS能调用这些API完成一些后端操作。 内置API模块(fs、path、http等) 第三方API模块(express、mysql等) fs模块 fs.readFile()方法,用于读取指定文件中的内容。 fs.writeFile()方…...

【git clone error:no matching key exchange method found】
拉起项目代码报错 git clone ssh://uidxxxgerrit-xxxxxxxx Cloning into ‘xxxxx’… Unable to negotiate with xxx.xx.xxx.ip port xxxxx: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 fatal: Could not …...

谈谈网络协议的定义、组成和重要性
个人主页:insist--个人主页 本文专栏:网络基础——带你走进网络世界 本专栏会持续更新网络基础知识,希望大家多多支持,让我们一起探索这个神奇而广阔的网络世界。 目录 一、网络协议的定义 二、网络协议的组成 1、…...

ssh免密登陆报错ERROR: @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
问题描述: 在日常的运维中需要做ssh的免密登陆有提示如下的报错内容: [rootpaas-harbor01 cce-v5.2.3]# ssh-copy-id 192.45.66.14 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /usr/bin/ssh-c…...

【kubernetes】Pod控制器
目录 Pod控制器及其功用 pod控制器有多种类型 1、ReplicaSet ReplicaSet主要三个组件组成 2、Deployment 3、DaemonSet 4、StatefulSet 5、Job 6、Cronjob Pod与控制器之间的关系 1、Deployment 查看控制器配置 查看历史版本 2、SatefulSet 为什么要有headless&…...

aspose.ocr 的图片识别
操作aspose.ocr版本 <dependency><groupId>aspose</groupId><artifactId>ocr</artifactId><version>23.7.1-SNAPSHOT</version></dependency>官网下载地址 https://releases.aspose.com/ocr/java/ 记录一些简单的识别图片操…...

安卓纯代码布局开发游戏二:Android Studio开发环境搭建
1.Android Studio下载: Download Android Studio & App Tools - Android Developers 2.安装 安装过程非常简单,找到下载包,一直点Next即可。 3.下载Android SDK 第一次进入Android Studio默认会先下载Android SDK,笔者下载的Android SDK存…...

HuggingFace开源的自然语言处理AI工具平台
HuggingFace是一个开源的自然语言处理AI工具平台,它为NLP的开发者和研究者提供了一个简单、快速、高效、可靠的解决方案,让NLP变得更加简单、快速、高效、可靠。 Hugging Face平台主要包括以下几个部分: Transformers:一个提供了…...

ant-design-vue在ios使用AUpload组件唤起了相机,HTML的 `capture` 属性
在使用ant design vue组件的上传组件AUpload的时候有一个问题,直接按照demo写,在ios上会唤起相机,但是实际上我们的需求是弹出选择相册/相机这个弹框。 解决办法是加一个 cupture"null"这个属性即可 <a-upload:capture"nu…...

力扣75——图深度优先搜索
总结leetcode75中的图深度优先搜索算法题解题思路。 上一篇:力扣75——二叉搜索树 力扣75——图深度优先搜索 1 钥匙和房间2 省份数量3 重新规划路线4 除法求值1-4 解题总结 1 钥匙和房间 题目: 有 n 个房间,房间按从 0 到 n - 1 编号。最初…...

小程序前台Boot后台校园卡资金管理系统java web学校进销存食堂挂失jsp源代码
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 小程序前台Boot后台校园卡资金管理系统 系统有2权限&…...

数学建模-多元线性回归笔记
数学建模笔记 1.学模型✅ 2.看专题论文并复习算法 多元线性回归 无偏性:预测值与真实值非常接近一致性:样本量无限增大,收敛于待估计参数的真值如何做:控制核心解释变量和u不相关 四类模型回归系数的解释 截距项不用考虑一元线性…...

云安全攻防(十二)之 手动搭建 K8S 环境搭建
手动搭建 K8S 环境搭建 首先前期我们准备好三台 Centos7 机器,配置如下: 主机名IP系统版本k8s-master192.168.41.141Centos7k8s-node1192.168.41.142Centos7k8s-node2192.168.41.143Centos7 前期准备 首先在三台机器上都执行如下的命令 # 关闭防火墙…...

Python学习笔记_基础篇(八)_正则表达式
1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则…...

【洛谷 P5736】【深基7.例2】质数筛 题解(判断质数)
【深基7.例2】质数筛 题目描述 输入 n n n 个不大于 1 0 5 10^5 105 的正整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。 输入格式 第一行输入一个正整数 n n n,表示整数个数。 第二行输入 n n n 个正整数 …...

C语言好题解析(一)
目录 选择题1选择题2选择题3选择题4编程题一 选择题1 执行下面程序,正确的输出是( )int x 5, y 7; void swap() {int z;z x;x y;y z; } int main() {int x 3, y 8;swap();printf("%d,%d\n",x, y);return 0; }A: 5,7 B: …...