java学习总结(六)Spring IOC

一、Spring框架介绍

Spring优点:

1、方便解耦,简化开发,IOC控制反转

Spring 就是一个大工厂,可以将所有对象创建和依赖关系维护交给Spring

2、AOP 编程的支持

Spring 提供面向切编程,可以方便的实现对序进行权限拦截、运监控等功能

3、声明式事务的支持(张三给李四转账,要么同时成功,要么同时失败)

只需要通过配置就可以完成对事务的管理,而无手动编程

4、方便集成各种优秀框架

Spring 不排斥各种优秀的开源框架,其内部提供了对各种优优秀框架的支持(如Struts,Mybatis,Hibernate)。

SSH SSM

二、IOC和DI

控制反转(Inversion on Control)IOC:对象的创建交给外部容器来完成(这里就是交给Spring容器),这就叫控制反转。

IOC:Spring就是一个大的内存容器(一块内存区域),三层架构里面上一层不需要再去new下一层对象,在上一层只需要写下一层的接口,new对象由Spring容器帮我们完成,各层直接向Spring容器要对象就可以。

class StudentController{// 需要什么,就去创建什么(自己去new),这就叫“控制正转”(通俗一点就是自己控制new哪个对象)private IStudentService studentService = new StudentServiceImpl();
}class StudentController{// 对象的创建交给别人去new(现在交给Spring容器new StudentServiceImpl(),new出来对方放在Spring容器),这就叫控制反转“IOC”private IStudentService studentService; // 将Spring容器中new出来的对象通过set方法赋值给studentService,这个过程叫依赖注入:DIpublic void setStudentService(IStudentService studentService) {this.studentService = studentService;}
} 

依赖注入:Dependency injection (DI)

现在new这个对象不是由自己new,是由Spring容器帮我们new对象,现在要得到这个Spring容器new出来的对象,就要“依赖”Spring容器,“注入”Spring容器new出来的对象。

IOC和DI区别:

IOC:解决对象创建的问题(对象的创建交给别人)Inversion of Control。

DI:在创建完对象后,对象关系的处理就是依赖注入(通过set方法实现依赖注入)Dependency injection。

先有IOC(对象创建),再有DI(处理对象关系)

在三层架构中最终实现的效果是:在Controller不会出现Service层具体的实现类代码,只会看到Service层接口,Service层也不会出现Dao层具体实现类的代码,也只会看到Dao层的接口

四、Bean的属性: scope范围

1、singleton

是scope的默认值,单例模式,在Spring容器中只存在一个实例。

public void test3() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Student student1 = (Student) context.getBean("student");Student student2 = (Student) context.getBean("student");System.out.println(student1 == student2);// true
}

2、prototype

多例,会创建多个对象,每次去容器里面拿会创建一个新的实例

<bean scope="prototype" name="student" class="com.situ.spring.pojo.Student"/>public void test3() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Student student1 = (Student) context.getBean("student");Student student2 = (Student) context.getBean("student");System.out.println(student1 == student2);// false
}

五、Spring属性注入方式

1、set方法注入

<bean name="banji" class="com.situ.spring.pojo.Banji"><property name="id" value="1"/><property name="name" value="Java2023"/>
</bean>
<bean name="student" class="com.situ.spring.pojo.Student"><!-- 值类型注入 --><property name="id" value="1"/><property name="name" value="张三"/><property name="age" value="23"/><property name="gender" value="男"/><!-- ref:reference参考、引用引用类型的注入--><property name="banji" ref="banji"/>
</bean>

2、构造方法注入

argument:参数

parameter:参数

<bean name="banji" class="com.situ.spring.pojo.Banji"><constructor-arg name="id" value="1"/><constructor-arg name="name" value="Java2023"/>
</bean>
<bean name="student" class="com.situ.spring.pojo.Student"><constructor-arg name="id" value="1"/><constructor-arg name="name" value="李四"/><constructor-arg name="age" value="23"/><constructor-arg name="gender" value="男"/><constructor-arg name="banji" ref="banji"/>
</bean>

3、注解方式注入

@Resource @Autowired

六、三层架构使用Spring来管理

1、set方法注入

三层架构使用Spring来管理,达到一个目的:在上层只看到下一层的接口就可以,不需要出现具体的实现类。

使用set方式注入:

<bean name="studentDao" class="com.situ.spring.dao.impl.StudentDaoImpl"/>
<bean name="studentService" class="com.situ.spring.service.impl.StudentServiceImpl"><property name="studentDao" ref="studentDao"/>
</bean>
<bean name="studentController" class="com.situ.spring.controller.StudentController"><property name="studentService" ref="studentService"/>
</bean>

2、注解开发方式

<!--base-package:是要扫描的包,扫描这个包下面类上带有注解@Controller @Service @Repositioy  -->
<context:component-scan base-package="com.situ.spring"/>

@Controller @Service @Repository 本身没有区别,都是new一个对象放到Spring容器中

@Component new一个对象放到Spring容器中,不起名字,放到容器中默认的名字是类名首个单词首字母小写

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {/*** The value may indicate a suggestion for a logical component name,* to be turned into a Spring bean in case of an autodetected component.* @return the suggested component name, if any (or empty String otherwise)*/@AliasFor(annotation = Component.class)String value() default "";}
/*
<bean name="courseController" class="com.situ.spring.controller.CourseController">
</bean>
@Controller 这个注解相当于在applicationContext.xml中写的上面的bean,
默认的名字是类名的首个单词小写courseController
*/
@Controller("courseController")
public class CourseController {// <property name="courseService" ref="courseService"/>// @Resource:从Spring容器中根据名字拿出指定的对象注入进来@Resource(name = "courseService")private ICourseService courseService;public void  selectAll() {System.out.println("CourseController.selectAll()");courseService.selectAll();}
}/*
<bean name="courseService" class="com.situ.spring.service.impl.CourseServiceImpl">
</bean>
*/
@Service("courseService")
public class CourseServiceImpl implements ICourseService{//<property name="courseDao" ref="courseDao"/>@Resource(name = "courseDao")private ICourseDao courseDao;@Overridepublic void selectAll() {System.out.println("CourseServiceImpl.selectAll()");courseDao.selectAll();}
}// <bean name="courseDao" class="com.situ.spring.dao.impl.CourseDaoImpl"></bean>
@Repository("courseDao")
public class CourseDaoIml implements ICourseDao{@Overridepublic void selectAll() {System.out.println("CourseDaoIml.selectAll()");}
}
@Controller、@Service、@Repository这三个注解的作用和@Component是一样的,都是new一个对象放到Spring容器中,目的是为了表明三层架构中不同的层。

七、Autowired 自动装配

1、@Autowired和@Resource区别

  1. @Resource默认是按照名称装配的,是JDK提供的。
byName 通过参数名自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。
  1. @Autowired是默认按照类型装配的 ,是Spring提供的。
byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配。

2、@Autowired一个接口有多个子类情况

@Service
public class BanjiServiceImpl implements IBanjiService {}@Service
public class BanjiServiceImpl2 implements IBanjiService{}

这样会报错: expected single matching bean but found 2: banjiServiceImpl,banjiServiceImpl2
因为在容器中子类对象有两个,而且变量的名字是banjiService和任何一个容器中对象的名字都不一致,所以找不到(只有一个子类对象情况下变量名可以随便写)
也同时证明,@Controller、@Service、@Repository不起名字,默认的名字是类的名字首字母变小写。
解决方法:
  1. 方法一:IBanjiService banjiServiceImpl2;
根据变量名去容器中找相同名字的bean对象,所以注入过来的是new BanjiServiceImpl2()的对象
  1. 方法二:还是希望写成IBanjiService banjiService,@Qualifier中限定名字
// @Resource(name = "banjiServiceImpl2")
@Autowired
@Qualifier(value = "banjiServiceImpl2")
private IBanjiService banjiService;

3、@Autowired注入bean

@Controller
public class StudentController {// <property name="studentService" ref="studentService"/>// @Resource(name = "studentService")@Autowiredprivate IStudentService studentService;}//@Service("studentService")
@Service
public class StudentServiceImpl implements IStudentService{// @Resource(name = "studentDao")@Autowiredprivate IStudentDao studentDao;}//@Repository("studentDao")
@Repository
public class StudentDaoImpl implements IStudentDao{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型推理:LM Studio在Mac上部署Deepseek-R1模型

LM Studio LM Studio是一款支持离线大模型部署的推理服务框架&#xff0c;提供了易用的大模型部署web框架&#xff0c;支持Linux、Mac、Windows等平台&#xff0c;并提供了OpenAI兼容的SDK接口&#xff0c;主要使用LLama.cpp和MLX推理后端&#xff0c;在Mac上部署时选择MLX推理…

AI技术学习笔记系列004:GPU常识

显卡架构是GPU设计的核心&#xff0c;不同厂商有其独特的架构演进。以下是主要厂商的显卡架构概述&#xff1a; 一、NVIDIA Tesla&#xff08;2006-2010&#xff09; 代表产品&#xff1a;GeForce 8000系列&#xff08;G80&#xff09;。特点&#xff1a;首款统一着色架构&…

实验- 分片上传 VS 直接上传

分片上传和直接上传是两种常见的文件上传方式。分片上传将文件分成多个小块&#xff0c;每次上传一个小块&#xff0c;可以并行处理多个分片&#xff0c;适用于大文件上传&#xff0c;减少了单个请求的大小&#xff0c;能有效避免因网络波动或上传中断导致的失败&#xff0c;并…

Android视频渲染SurfaceView强制全屏与原始比例切换

1.创建UI添加强制全屏与播放按钮 2.SurfaceView控件设置全屏显示 3.全屏点击事件处理实现 4.播放点击事件处理 5.使用接口更新强制全屏与原始比例文字 强制全屏/原始比例 点击实现

数据结构——串、数组和广义表

串、数组和广义表 1. 串 1.1 串的定义 串(string)是由零个或多个字符组成的有限序列。一般记为 S a 1 a 2 . . . a n ( n ≥ 0 ) Sa_1a_2...a_n(n\geq0) Sa1​a2​...an​(n≥0) 其中&#xff0c;S是串名&#xff0c;单引号括起来的字符序列是串的值&#xff0c; a i a_i a…

无再暴露源站!群联AI云防护IP隐匿方案+防绕过实战

一、IP隐藏的核心原理 群联AI云防护通过三层架构实现源站IP深度隐藏&#xff1a; 流量入口层&#xff1a;用户访问域名解析至高防CNAME节点&#xff08;如ai-protect.example.com&#xff09;智能调度层&#xff1a;基于AI模型动态分配清洗节点&#xff0c;实时更新节点IP池回…

1.5.3 掌握Scala内建控制结构 - for循环

Scala的for循环功能强大&#xff0c;支持单重和嵌套循环。单重for循环语法为for (变量 <- 集合或数组 (条件)) {语句组}&#xff0c;可选筛选条件&#xff0c;循环变量依次取集合值。支持多种任务&#xff0c;如输出指定范围整数&#xff08;使用Range、to、until&#xff0…

【MySQL基础-9】深入理解MySQL中的聚合函数

在数据库操作中&#xff0c;聚合函数是一类非常重要的函数&#xff0c;它们用于对一组值执行计算并返回单个值。MySQL提供了多种聚合函数&#xff0c;如COUNT、SUM、AVG、MIN和MAX等。这些函数在数据分析和报表生成中扮演着关键角色。本文将深入探讨这些聚合函数的使用方法、注…

windows版本的时序数据库TDengine安装以及可视化工具

了解时序数据库TDengine&#xff0c;可以点击官方文档进行详细查阅 安装步骤 首先找到自己需要下载的版本&#xff0c;这边我暂时只写windows版本的安装 首先我们需要点开官网&#xff0c;找到发布历史&#xff0c;目前TDengine的windows版本只更新到3.0.7.1&#xff0c;我们…

Web测试

7、Web安全测试概述 黑客技术的发展历程 黑客基本涵义是指一个拥有熟练电脑技术的人&#xff0c;但大部分的媒体习惯将“黑客”指作电脑侵入者。 黑客技术的发展 在早期&#xff0c;黑客攻击的目标以系统软件居多。早期互联网Web并非主流应用&#xff0c;而且防火墙技术还没有…

华为OD机试 - 最长的完全交替连续方波信号(Java 2023 B卷 200分)

题目描述 给定一串方波信号,要求找出其中最长的完全连续交替方波信号并输出。如果有多个相同长度的交替方波信号,输出任意一个即可。方波信号的高位用1标识,低位用0标识。 说明: 一个完整的信号一定以0开始并以0结尾,即010是一个完整的信号,但101,1010,0101不是。输入的…

游戏引擎学习第163天

我们可以在资源处理器中使用库 因为我们的资源处理器并不是游戏的一部分&#xff0c;所以它可以使用库。我说过我不介意让它使用库&#xff0c;而我提到这个的原因是&#xff0c;今天我们确实有一个选择——可以使用库。 生成字体位图的两种方式&#xff1a;求助于 Windows 或…

7、什么是死锁,如何避免死锁?【高频】

&#xff08;1&#xff09;什么是死锁&#xff1a; 死锁 是指在两个或多个进程的执行时&#xff0c;每个进程都持有资源 并 等待其他进程 释放 它所需的资源&#xff0c;如果此时所有的进程一直占有资源而不释放&#xff0c;就会陷入互相等待的一种僵局状态。 死锁只有同时满足…

Compose 实践与探索十四 —— 自定义布局

自定义布局在 Compose 中相对于原生的需求已经小了很多&#xff0c;先讲二者在本质上的逻辑&#xff0c;再说它们的使用场景&#xff0c;两相对比就知道为什么 Compose 中的自定义布局的需求较小了。 原生是在 xml 布局文件不太方便或者无法满足需求时才会在代码中通过自定义 …

【C++】:C++11详解 —— 入门基础

目录 C11简介 统一的列表初始化 1.初始化范围扩展 2.禁止窄化转换&#xff08;Narrowing Conversion&#xff09; 3.解决“最令人烦恼的解析”&#xff08;Most Vexing Parse&#xff09; 4.动态数组初始化 5. 直接初始化返回值 总结 声明 1.auto 类型推导 2. declty…

oracle删除表中重复数据

需求&#xff1a; 删除wfd_procs_nodes_rwk表中&#xff0c;huser_id、dnode_id、rwk_name字段值相同的记录&#xff0c;如果有多条&#xff0c;只保留一条。 SQL&#xff1a; DELETE FROM wfd_procs_nodes_rwk t WHERE t.rowid > (SELECT MIN(t1.rowid)FROM wfd_procs_n…

ESP32学习 -从STM32工程架构进阶到ESP32架构

ESP32与STM32项目文件结构对比解析 以下是对你提供的ESP32项目文件结构的详细解释&#xff0c;并与STM32&#xff08;以STM32CubeIDE为例&#xff09;的常见结构进行对比&#xff0c;帮助你理解两者的差异&#xff1a; 1. ESP32项目文件解析 文件/目录作用STM32对应或差异set…

整形在内存中的存储(例题逐个解析)

目录 一.相关知识点 1.截断&#xff1a; 2.整形提升&#xff1a; 3.如何 截断&#xff0c;整型提升&#xff1f; &#xff08;1&#xff09;负数 &#xff08;2&#xff09;正数 &#xff08;3&#xff09;无符号整型&#xff0c;高位补0 注意&#xff1a;提升后得到的…

HTML中滚动加载的实现

设置div的overflow属性&#xff0c;可以使得该div具有滚动效果&#xff0c;下面以div中包含的是table来举例。 当table的元素较多&#xff0c;以至于超出div的显示范围的话&#xff0c;观察下该div元素的以下3个属性&#xff1a; clientHeight是div的显示高度&#xff0c;scrol…

Netty基础—7.Netty实现消息推送服务二

大纲 1.Netty实现HTTP服务器 2.Netty实现WebSocket 3.Netty实现的消息推送系统 (1)基于WebSocket的消息推送系统说明 (2)消息推送系统的PushServer (3)消息推送系统的连接管理封装 (4)消息推送系统的ping-pong探测 (5)消息推送系统的全连接推送 (6)消息推送系统的HTTP…