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/ 记录一些简单的识别图片操…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
手动给中文分词和 直接用神经网络RNN做有什么区别
手动分词和基于神经网络(如 RNN)的自动分词在原理、实现方式和效果上有显著差异,以下是核心对比: 1. 实现原理对比 对比维度手动分词(规则 / 词典驱动)神经网络 RNN 分词(数据驱动)…...





