四,Spring注解开发

news2024/11/17 11:39:14

Spring day04

1 Spring基于注解的开发

XML方式配置bean存在的问题:开发效率低下。Spring2.x提供了开发效率更高的注解式配置。注解开发替换XML配置的好处:简化编程,提高开发效率。

  • XML方式:配置繁琐,但功能强大,维护性好,可配置第3方类型(非自己编码的类型)
  • 注解方式:配置简单,开发效率高。一般用于自定义类型的配置

1.1 注解开发的思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lQL1p8z8-1673747421009)(Spring day04.assets/image-20210617223657666.png)]

1.2 注解开发的步骤

  1. 查找注解,配置查找注解的起始包名

    applicationContext.xml

     <!-- 扫描指定包下以及子包下所有使用注解的类,自动配置为Bean-->
    <context:component-scan base-package="com.bz"/>
    
  2. 为类和属性添加注解

    package com.bz.service.impl;
    
    import com.bz.entity.User;
    import com.bz.mapper.UserMapper;
    import com.bz.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserMapper userMapper;
    
        public void setUserMapper(UserMapper userMapper) {
            this.userMapper = userMapper;
        }
    
        @Override
        public boolean login(String name, String password) {
            User user = userMapper.selectUserByName(name);
    
            return user!= null && user.getPassword().equals(password);
        }
    
    
    }
    

1.3 核心注解

1.3.1 bean配置相关注解

@Component替换bean标签,创建对象。

@Controller 用在action层
@Service 用在service
@Repository 用在dao层

@Service
//@Component("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
	...
}

注意:

  1. Controller Service Repository和Component作用一样,但更有识别性。

  2. MyBatis框架下,Repository注解没有必需的使用场景

  3. 4个注解使用时,都可以不用设置id属性,id默认值:类名首字母小写

    例如:UserServiceImpl ==> userServiceImpl

@Scope 决定对象是否单例

​ 默认对象是单例的,可以通过@Scope(“prototype”)设置为多例

1.3.2 属性注入的相关注解

@Autowired 用来完成属性注入。

@Service
public class UserServiceImpl implements UserService {
    @Autowired(required = false)
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    ...
}

注意:

  1. Autowired根据属性的类型,从Spring容器中获取对象,完成属性赋值
  2. Autowired用在属性上,通过反射直接操作属性为属性赋值,不会使用set方法
  3. Autowired还可以用在set方法上,此时通过调用属性的set方法赋值
  4. Autowired修饰的属性默认是必须的,如果注入失败就会抛出异常;可以设置@Autowired(required=false)允许注入失败

@Qualifier(“bean的id”)

与@Autowired配合使用,当有多个满足属性类型要求的Bean时,可以用@Qualifier(“id”)来指定要注入的依赖。

class Address{
    private String city;
    private String address;
    ...
}
<bean id="addr1" class="com.bz.entity.Address">
	<property name="city" value="郑州"/>
    <property name="street" value="文化路"/>
</bean>
<bean id="addr2" class="com.bz.entity.Address">
	<property name="city" value="郑州"/>
    <property name="street" value="白庙路"/>
</bean>
class Person{
    private String personName;
    
    @Autowired
    @Qualifier("addr1")
    private Address addr;
    ...
}

@Value用于为简单属性赋值,还可以读取properties文件中的参数

jdbc.properties

url=jdbc:mysql://localhost:3306/spring?useUnicde=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=Asia/Shanghai
driverClassName=com.mysql.cj.jdbc.Driver
user=root
password=123456

JdbcProeprties.java

@Component
public class JdbcProperties{
    //@Value("root")
    @Value("${user}")
    private String username;
    @Value("${password}")
    private String password;
    @Value("${url}")
    private String url;
    @Value("${driverClassName}")
    private String driverClassName;
    
    ...
}

行业标准:

  1. 自定义类型Service、Dao使用注解开发
  2. 第3方类型:数据库连接池、事务管理器…使用xml配置

2 基于注解的事务控制

使用Transactional注解描述类或者方法添加事务。

开发步骤:

  1. 创建原始对象

  2. 定义通知类(功能增强:事务控制)

    Spring内置的DataSourceTransactionManager

  3. 配置通知类

    <!-- 配置事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    </bean>
    
    <tx:annotation-driven transaction-manager="txManager"/>
    
  4. 使用Transactional注解描述类或方法

    @Service
    @Transactional
    public class UserServiceImpl implements UserService {
    	@Autowired
        private UserDao userDao;
    
        @Transactional(readOnly=true)
         @Override
        public boolean login(String name, String password) {
            User user = userDao.selectUserByName(name);
    
            return user!= null && user.getPassword().equals(password);
        }
        
        public void register(String username,String password){
            userDao.insertUser(new User(null,username,password));
        }
    }
    

注意:

传统的Spring项目中,注解的事务控制使用较少,更多的还是使用xml配置的事务控制。但是在SpringBoot中大量的使用注解方式的事务配置。

3 Spring集成JUnit

直接使用JUnit测试Spring项目,需要手动编码获取context工厂,需要手动从工厂中获取对象,测试繁琐。
解决方案:使用Spring-test,简化了Spring项目的测试。

准备工作:导入JUnit、spring-test依赖

<!-- junit版本必须是4.12及以上-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

测试:

//开启Spring对Junit的支持
@RunWith(SpringRunner.class)
//设置配置文件的路径
@ContextConfiguration("classpath:applicationContext.xml")
public class ApplicationContextTest {
    //自动从工厂中获取对象,为属性赋值
    @Autowired
    private ApplicationContext context;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserService userService;
    
    ...
}

小技巧:如果有多个测试类,多个测试类上方也有重复的配置,可以定义父类抽取共性

//开启Spring对Junit的支持
@RunWith(SpringRunner.class)
//设置配置文件的路径
@ContextConfiguration("classpath:applicationContext.xml")
public abstract class AbstractApplicationContextTest {
}

public class ApplicationContextTest extends AbstractApplicationContextTest{
    @Autowired
    private UserService userService;
    ...
}

4 再谈web.xml

4.1 web.xml标签的加载顺序

目前为止学习的标签:servlet filter listener context-param

加载顺序:

  1. context-param
  2. listener
  3. filter
  4. servlet

4.2 servlet的url-pattern配置形式以及优先级

url-pattern配置形式种类:

  1. 精确匹配

    /student/showPageStudents

  2. 路径匹配

    /* /student/*

  3. 扩展名匹配

    *.jsp *.do *.action

  4. 缺省匹配

    / 在前3种都无法匹配时做默认匹配

优先级:精确匹配>路径匹配>扩展名匹配>缺省匹配

注意:

  1. 都是路径匹配时,最长路径优先

    http://localhost:8989/spring-day05/student/b

    /student/* 比/* 优先匹配到。

  2. 路径匹配和扩展名匹配不能混用

    不能出现如下配置:

    /student/*.do

    / * / *.jsp

另外注意:

  1. Filter一定早于Servlet执行
  2. 多个Filter执行的优先级只跟配置顺序有关,跟url-pattern的优先级没有关系

5 事务详解(概念重点)

5.1 read-only

read-only="true"表示只读事务,提高查询(检索)效率。read-only的默认值是false。
注意:只能应用到查询操作,不能应用到增删操操作上。

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <!-- 所有以show开头的方法,执行只读的事务-->
        <tx:method name="show*" read-only="true"/>
        <!-- 除了show开头的其它所有方法,执行读写的事务(false也是默认值)-->
        <tx:method name="*" read-only="false"/>
    </tx:attributes>
</tx:advice>

5.2 timeout

timeout超时机制(单位秒):事务执行时间超过指定的时长后,自动失败回滚。
timeout默认值-1:表示跟数据库的默认超时设置有关。

//通过sleep方法,模拟业务方法执行超时
public void removeUser(Integer id) {
    try {
        Thread.sleep(5000);//当前线程睡眠5s
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    userDao.deleteUserById(id);
}
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="show*" read-only="true"/>
        <!-- 超时时间时间设置为3s-->
        <tx:method name="*" timeout="3"/>
    </tx:attributes>
</tx:advice>
@Test
//测试超时
public void testTimeout(){
     ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserService userService = (UserService)ctx.getBean("userServiceImpl");
    userService.removeUser(1);
}

5.3 rollback-for和no-rollback-for

rollback-for:当发生rollback-for配置的异常类型的异常时,执行回滚。
no-rollback-for:当发生no-rollback-for配置的异常类型的异常时,不执行回滚。

Spring中默认:

RuntimeException及其子类(运行时异常)的异常执行回滚

Exception及其子类(编译时异常)的异常不会执行回滚

public void addUser(User u) {
    userDao.insertUser(u);
    // throw new RuntimeException("自定义未检查异常");//默认回滚
    throw new Exception("自定义已检查异常");//默认不回滚
}

rollback-for和no-roollback-for的生效规则:

  • 2个的属性本身没有优先级区别
  • 程序产生的异常,与哪个属性中配置的异常类型继承关系更近就是用哪个配置
  • 如果产生的异常和配置的异常类型没有继承关系,则使用默认规则

5.4 propagation(传播机制)

企业开发中,会出现业务层方法调用业务层方法的情况。propagation定义了一个业务方法被另外一个业务方法调用时的事务传播方式。

常用的事务传播机制:

传播机制内部方法对事务的要求特点
REQUIRED必须有如果外部有事务,则加入;外部没有事务,则新建
REQUIRES_NEW必须有无论外部是否有事务,内部都会新建
SUPPORTS可有可无如果外部有事务则加入;如果没有则以无事务状态运行
NOT_SUPPORTED必须没有如果外部有事务,则挂起外部事务
MANDATORY必须有如果外部没有事务,直接抛出异常
NEVER必须没有如果外部有事务,直接抛出异常
NESTED必须有如果外部没有事务,开启事务;如果外部有事务,记录当前的保存点;一旦出错,不会全部回滚,只回滚到保存点

5.5 isolation(隔离级别)

解决事务并发执行的问题,微观上,2个执行时间相近的事务相互影响的问题。

5.5.1 4种标准的隔离级别

隔离性在数据库的并发访问时得以体现,随着数据库并发事务处理能力的大大增强,数据库资源的利用率也会大大提高,从而提高了数据库系统的事务吞吐量,可以支持更多的用户并发访问。但并发事务处理也会带来一些问题,如:脏读、不可重复读、幻读。这些问题是和隔离性相伴相生的。下面一一解释其含义。

  • 脏读

    B事务正在对一条记录做修改,在这个事务提交前,这条记录的数据就处于不一致状态;这时,另一个事务A也来读取同一条记录,如果不加控制,第二个事务读取了这些未提交的(“脏”)数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫作"脏读"(Dirty Reads)。

  • 不可重复读

    一个事务中多次执行相同的查询SQL,不同时刻读取的数据不同。要么发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫作“ 不可重复读”(Non-Repeatable Reads)。

  • 幻读

    一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”(Phantom Reads)。

隔离级别特点存在的问题
READ-UNCOMMITTED读未提交脏读、不可重复读、幻读
READ-COMMITTED读已提交只能读到另外一个事务提交后的数据。不可重复读、幻读
REPEATABLE-READ可重复读同一个事务下,前后两次结果一致不同数据库不同,有的数据库会有幻读
SERIALIZABLE序列化读串行性能太差

Oracle只支持READ-COMMITTED和SERIALIZABLE 2种隔离级别。

MySQL支持4种。

实战时,使用读已提交即可。

5.5.2 MySQL下演示隔离级别

MySQL支持多种存储引擎:InnoDB(支持事务)、MyISAM、MEMORY

存储引擎:决定了数据库如何的保存管理数据。

  1. 确认MySQL使用的存储引擎
show engines;//查询数据库支持的存储引擎
show variables like 'default_storage_engine';//查询默认引擎

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3NbDFE9k-1673747421010)(Spring day04.assets/image-20200406163015651.png)]

  1. 查询当前使用的隔离级别:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mk7KSqyh-1673747421011)(Spring day04.assets/image-20200406163149179.png)]

  2. 修改当前使用的隔离级别:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZGwkePr-1673747421011)(Spring day04.assets/image-20200406163503131.png)]

  3. MySQL中开启事务和结束事务

    >start transaction;//开启事务
    >commit;//提交
    >rollback;//回滚
    

隔离级别

准备工作:

create table t_account(
	id int primary key,
    money double
);
start transaction;
insert into t_account values(1,100);
insert into t_account values(2,200);
commit;
  1. 读未提交隔离级别[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRqsFGUG-1673747421012)(Spring day04.assets/image-20200406170439133.png)]

    脏读:B事务未提交,A事务可以读取到B事务插入的数据

  2. 读提交隔离级别

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SrrMkJY-1673747421012)(Spring day04.assets/image-20210508221628304-1624412671148.png)]

    B事务不提交,A事务读取不到。B事务提交后A事务就可以读取到。

    仍存在的问题:不可重复读和幻读

  3. 可重复读隔离级别

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pxcOqJoQ-1673747421013)(Spring day04.assets/image-20210509185633571.png)]

  4. 序列化读

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjhwJf7f-1673747421013)(Spring day04.assets/image-20200406171658872-1624412785930.png)]

    文章对应源码地址:https://download.csdn.net/download/qq_36827283/87386038

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

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

相关文章

测试开发的一次实践总结

这些年&#xff0c;测开越来越火&#xff0c;火的原因之一就是因为大部分公司都有设测开岗位并有招聘需求。那测试开发到底是做什么&#xff0c;和测试又有什么区别呢&#xff1f;接下来&#xff0c;说说我对测开的理解与实际工作的总结。 01—测试开发的理解 测试分类 从市场…

测试碎碎念(基础篇_1)

一、软件测试1.1 什么是测试测试行为 在生活中是十分常见的~在生活中&#xff0c;我们有许多 "测试" 的行为&#xff0c;比如说&#xff0c;在坐地铁之前&#xff0c;需要用金属探测仪在身上刷一下&#xff0c;需要把身上的背包等物品放在闸机上过一下~比如说&#x…

Rockchip开发系列 - 8. IO电源域配置

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 RK3566 RK3568 IO 电源域配置指南概述第一步:获取硬件原理图并确认硬件电源的设计方案第二步:查找对应的内核dts配置文件第三步:修…

Open3D 网格滤波(Python版本)

文章目录 一、简介二、滤波2.1 均值滤波2.2 Laplacian滤波2.3 Taubin滤波三、实现效果参考资料一、简介 网格数据的滤波其本质上仍是针对点的滤波过程,具体的过程如下所示。 二、滤波 2.1 均值滤波 如下公式所示,均值滤波其实就是该点与其邻近点之间的平均值: Open3D中的相…

在Ubuntu上安装OpenShift并使用

服务器信息 在阿里云买了个抢占式的服务器&#xff0c;地区为华南广州&#xff0c;系统为Ubuntu 20.04&#xff0c;8核16GB。 安装Docker 命令如下&#xff1a; $ apt-get update -y $ apt-get upgrade -y $ apt-get install -y docker.io 安装成功后&#xff0c;检查一下版…

2023 年你应该知道的所有机器学习算法

在过去的几年里&#xff0c;根据自己的工作经验&#xff0c;整理了我认为最重要的机器学习算法。 通过这个&#xff0c;我希望提供一个工具和技术的存储库&#xff0c;以便您可以解决各种数据科学问题&#xff01; 让我们深入研究六种最重要的机器学习算法&#xff1a; 解释…

状态机原理

前言状态机在实际工作开发中应用非常广泛&#xff0c;在刚进入公司的时候&#xff0c;根据公司产品做流程图的时候&#xff0c;发现自己经常会漏了这样或那样的状态&#xff0c;导致整体流程会有问题&#xff0c;后来知道了状态机这样的东西&#xff0c;发现用这幅图就可以很清…

简单步骤比别人抢红包快一步

&#x1f935;‍♂️ 个人主页老虎也淘气 个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f44d;&#x1f3fb; 收藏…

Slurm中集群配置文件slurm.conf

1.slurm.conf简介slurm.conf是一个ASCII文件&#xff0c;它描述了一般的Slurm 配置信息、要管理的节点、有关如何将这些节点分组到分区中&#xff0c;以及各种调度与这些分区关联的参数。此文件应为在群集中的所有节点上保持一致。可以通过设置SLURM_CONF在执行时修改文件位置 …

203:vue+openlayers 地图旋转移动动画、CSS缩放动画,介绍animate的使用方法

第203个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers项目中创建动画,地图上使用的是view中的animate方法, CSS中使用的是keyframes ,animation,transform等方法。这两将两者融合在一个示例中,api用的不全,但是能起到一个抛转引玉的作用。 地图 view.anima…

Java while和do while循环详解

循环是程序中的重要流程结构之一。循环语句能够使程序代码重复执行&#xff0c;适用于需要重复一段代码直到满足特定条件为止的情况。所有流行的编程语言中都有循环语句。Java 中采用的循环语句与C语言中的循环语句相似&#xff0c;主要有 while、do-while 和 for。另外 Java 5…

ROS2机器人编程简述humble-第一章-Introduction

ROS2机器人编程简述新书推荐-A Concise Introduction to Robot Programming with ROS2学习笔记流水账-推荐阅读原书。第一章&#xff1a;简要介绍宏观概念&#xff0c;配置编译一下本书配套的源码包。支持版本个人测试foxy和humble全部都OK。硬件软件机器人应用关系如下图所示&…

【阶段四】Python深度学习01篇:深度学习基础知识:神经网络历史及优势、神经网络基础单元与梯度下降:正向传播和反向传播

本篇的思维导图: 神经网络历史及优势 1958年,计算机科学家罗森布拉特(Rosenblatt)就提出了一种具有单层网络特性的神经网络结构,称为“感知器”(perceptron)。感知器出现之后很受瞩目,大家对它的期望很高。然而好景不长—一段时间后,人们发现感知器的实用性很…

2022.12 青少年机器人技术等级考试理论综合试卷(一级)

2022年12月 青少年机器人技术等级考试理论综合试卷&#xff08;一级&#xff09; 分数&#xff1a; 100 题数&#xff1a; 45 一、 单选题(共 30 题&#xff0c; 共 60 分) 1.下列哪个是机器人?&#xff08; &#xff09; A.a B.b C.c D.d 标准答案&#xff1a; C 2.机器人的电…

1-计算机系统概述(CO)

计算机组成原理&#xff1a;实现计算机体系结构所体现的属性&#xff0c;具体指令的实现对程序员透明&#xff0c;即研究如何用硬件实现所定义的接口 计算机系统硬件&#xff08;计算机的实体&#xff0c;如主机、外设&#xff09;软件&#xff08;由具有各类特殊功能的程序组…

【博客587】ipvs hook点在netfilter中的位置以及优先级

ipvs hook点在netfilter中的位置以及优先级 1、netfilter栈全景图 2、Netfilter hooks 五个hook点&#xff1a; 每个 hook 在内核网络栈中对应特定的触发点位置&#xff0c;以 IPv4 协议栈为例&#xff0c;有以下 netfilter hooks 定义&#xff1a; NF_INET_PRE_ROUTING:…

深入理解数据结构 —— 差分

什么是差分 对于一个数组a&#xff1a;a1,a2,a3...an 我们构造一个数组b&#xff1a;b1,b2,b3...bn 使得数组a是数组b的前缀和数组&#xff0c;即ai b1 b2 ... bi 则数组b就是数组a的差分 差分有什么用 当我们得到数组b后&#xff0c;只用对b求一遍前缀和&#xff0c;…

使用ChatGPT智能搜索论文

对于天天查找论文的小伙伴来说&#xff0c;有一个好用的搜索工具&#xff0c;那简直不要太开心&#xff0c;效率妥妥的上升。但现实结果却是&#xff0c;要么搜索工具不给力&#xff0c;要么自己输入的关键词不起作用&#xff0c;反正&#xff0c;自己脑海里想找寻的论文和搜索…

大数据必学Java基础(一百二十三):Maven常见命令介绍

文章目录 Maven常见命令介绍 一、install 二、clean 三、compile 四、package Maven常见命令介绍 Maven的命令非常多,我们只是讲解常用的几个:(所有命令都可以在控制台运行的)

Linux——页表的分页机制

目录 一.相关概念&#xff08;页帧、页框、缺页中断&#xff09; 二.页表分页机制 &#xff08;一&#xff09;.为什么采用两级页表 &#xff08;二&#xff09;.两级页表分页机制 ①原理&#xff1a; ②映射原理计算 一.相关概念&#xff08;页帧、页框、缺页中断&#…