1. Spring
1.1 简介
1.2 优点
-
Spring是一个开源的免费的框架(容器)
-
Spring是一个轻量级的,非入侵式的框架!
-
控制反转 (IOC) ,面向切面编程(AOP)
-
支持事务的处理, 对框架整合的支持
总结: Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!
1.3 组成
1.4 拓展
官网介绍: 现代化的java开发! 基于spring开发!
- SpringBoot
- 一个快速开发的脚手架
- 基于SpringBoot可以快速的开发单个微服务
- 约定大于配置!
- SpringCloud
- SpringCloud是基于SpringBoot实现的
因为大多数公司都在使用SpringBoot进行快速开发, 学习SpringBoot的前提,需要完全掌握Spring一级SpringMVC!承上启下的作用!
弊端: 发展了太久之后, 违背了原来的理念!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UvvEYp0D-1679916395534)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230321105450006.png)]
2. IOC理论推导
IOC本质
3. HelloSpring
4. IOC创建对象的方式
- 使用无参构造创建对象, 默认!
- 假设我们要使用有参构造创建对象!
总结: 在配置文件加载的时候, 容器中管理就已经初始化了!
5.Spring配置
5.1 别名
<!-- 如果使用了别名, -->
<alias name="user" alias="userNew"/>
5.2 Bean的配置
5.3 import
6. 依赖注入
6.1 构造器注入
6.2 Set方式注入
- 依赖注入: Set注入
- bean对象创建依赖 容器
- bean对象中的所有属性, 有 容器来注入!!
环境搭建
- 复杂类型
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
- 真实测试对象
public class Student {
private String name;
private Address address;
private String[] bookes;
private List<String> hobbies;
private Map<String, String> card;
private String wife;
private Set<String> games;
private Properties info;
}
- beans.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">
<bean id="student" class="com.ljs.pojo.Student">
<!-- 1. 普通纸注入, value设置 -->
<property name="name" value="张三丰"></property>
<property name="address" value="广西南宁"></property>
</bean>
</beans>
- 测试类
public class MyTest {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.toString());
}
}
完善注入信息:
<bean id="address" class="com.ljs.pojo.Address">
<property name="address" value="南宁"></property>
</bean>
<bean id="student" class="com.ljs.pojo.Student">
<!-- 1. 普通纸注入, value设置 -->
<property name="name" value="张三丰"></property>
<!-- 2. Bean注入, ref -->
<property name="address" ref="address"></property>
<!-- 数组注入, ref -->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
<value>金瓶梅</value>
</array>
</property>
<!-- list -->
<property name="hobbies">
<list>
<value>听歌</value>
<value>看电影</value>
<value>敲代码</value>
</list>
</property>
<!-- Map -->
<property name="card">
<map>
<entry key="身份证" value="123456789132456"></entry>
<entry key="银行卡" value="621722222555555555555"></entry>
</map>
</property>
<!-- Set -->
<property name="games">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!-- null -->
<property name="wife">
<null/>
</property>
<!-- Properties -->
<property name="info">
<props>
<prop key="学号">20220255</prop>
<prop key="性别">男</prop>
<prop key="username">张三丰</prop>
<prop key="pad">123456</prop>
</props>
</property>
</bean>
6.3 拓展方式注入
我们可以使用p命名空间和c命名空间进行注入
官方解释:
注意点: p和c命名空间不能直接使用, 需要导入xml约束
xmlns:p=“http://www.springframework.org/schema/p”
xmlns:c=“http://www.springframework.org/schema/c”
p命名空间
c命名空间
xmlns:c=“http://www.springframework.org/schema/c”
6.4 bean作用域
- 单例模式 (Spring 默认机制)
-
原型模式: 每次从容器中get的时候, 都会产生一个新的对象!
-
其余的Request、 Session、 Application 这些只能在web开发中使用到!
7. bean的自动装配
- 自动装配是Spring满足bean依赖的一种方式!
- Spring会在上下文中自动寻找, 并自动 给bean装配属性!
在Spring中有三种装配的方式
- 在xml中显示的配置
- 在java中显示配置
- 隐式的自动装配bean
7.1 测试
环境搭建: 一个人两个宠物
7.2 ByName自动装配
7.3 byType 自动装配
7.4 使用注解实现自动装配
jdk1.5 支持的注解, Spring2.5支持的注解
要使用注解须知:
- 导入约束 xmlns:context=“http://www.springframework.org/schema/context”
- 配置注解的支持 context:annotation-config/
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解 -->
<context:annotation-config/>
</beans>
@Autowired
直接在属性上使用即可!也可以在set方法上使用!
使用Autowired 我们可以不用编写Set方法了, 前提是你这个自动装配的属性在IOC(Spring) 容器中存在 且符合名字byname!
科普:
@NullAble
@Resource注解
小结:
@Autowired和@Resource的区别
- 都是用来自动装配的,都可以放在属性字段上
8. 使用注解开发
在Spring4之后,要使用注解开发,必须保证aop的包的导入了
- bean
- 属性如何注入
@Component
public class User {
@Value("张三丰")
private String name;
}
- 衍生的注解
@Component
- 自动装配置
## 1. @Autowired
**自动转配,通过类型,名字;**
**如果Autowired不能唯一自动装配属性,则需要通过@Qualifier(value="xxx")**
## 2.@Nullable
**字段标记 了这个注解,说明这个字段可以为null**
## 3. @Resource
**自动装配通过名字, 类型**
-
作用域
@Component//组件标识bean @Scope("singleton")//作用域 public class User { @Value("张三丰")//set注入属性值 private String name; }
-
小结
xml 与注解:
- xml 更万能, 使用与任何场合,维护简单方便!
- 注解 不是自己的类使用不了,维护相对复杂
xml 与 纾解最佳实践
- xml 用来管理bean
- 注解只负责完成属性的注入
- 我们在使用的过程中, 只需要注意一个问题: 必须让注解生效, 就需要开启注解的支持
<!-- 注解驱动: 开启注解 -->
<context:annotation-config/>
<!-- 扫描的包 -->
<context:component-scan base-package="com.ljs"></context:component-scan>
9. 使用Java的方式配置Spring
我们现在要完全不适用Spring的xml配置,全权交个Java来做!
JavaConfig 是Spring的一个子项目, 在Spring4之后, 他成为了一个核心的功能!
配置类:
@Import(xxx.class)
实体类:
测试类:
10. 代理模式
代理模式的分类:
- 静态代理
- 动态代理
10.1 静态代理
角色分析:
- 抽象角色: 一般会使用接口或者抽象类来角色
- 真实角色: 被代理的角色
- 代理角色: 代理真实角色, 代理真实角色后, 我们一般会做一些附属的操作
- 客户: 访问代理对象的人!
代码步骤:
- 接口
public interface Rent {
public void rent();
}
- 真实角色
public class Host implements Rent{
public void rent() {
System.out.println("房东要出租房子!");
}
}
- 代理角色
public class Proxy {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
seeHouse();
host.rent();
contract();
pare();
}
//看房
public void seeHouse() {
System.out.println("中介带你看房子!");
}
//前租赁合同
public void contract() {
System.out.println("前租赁合同");
}
//收中介费
public void pare() {
System.out.println("收中介费");
}
}
- 客户端访问代理角色
public class Client {
public static void main(String[] args) {
//房东要出租房子
Host host = new Host();
//代理, 中介帮房东出租房子, 代理角色一般会做一些附属操作!
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
代理模式的好处:
- 可以使真实角色的操作更加纯粹! 不用关心一些公共的业务
- 公共也就交给代理角色,实现了业务的分工!
- 公共业务发生拓展的时候,方便集中管理!
缺点:
- 一个真实角色就产生一个代理角色; 代码量会翻倍, 开发效率变低!
10.2 加深理解
10.3 动态代理
- 动态代理和静态代理角色一样;
- 动态代理的代理类是动态生成的, 不是我们直接写好的!
- 动态代理分为两大类: 基于接口的动态代理; 基于类的动态代理
- 基于接口: —JDK 动态代理
- 基于类 : cglib
- java 字节码实现: JAVAssist
需要了解两个类: Proxy :代理 , InvocationHandler: 调用处理程序
动态代理的好处:
- 可以使真实角色的操作更加纯粹! 不用关心一些公共的业务
- 公共也就交给代理角色,实现了业务的分工!
- 公共业务发生拓展的时候,方便集中管理!
- 一个动态代理类代理的是一个接口, 一般就是对应的是一类业务;
- 一个动态代理类可以代理多个类.只要是实现了同一个接口即可!
11. AOP
11.1 什么是AOP
11.2 AOP在Spring中作用
提供声明式事务;允许用户自定义切面
11.3 使用Spring实现AOP
[重点] 使用AOP植入,需要一个依赖包!
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
方式一: 使用原生Spring API实现接口
- 准备业务接口
package com.ljs.service;
public interface UserService {
public void add();
public void delete();
public void edit();
public void select();
}
- 实现类
package com.ljs.service;
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("add one --------");
}
public void delete() {
System.out.println("delete one--------");
}
public void edit() {
System.out.println("edit one --------");
}
public void select() {
System.out.println("select one--------");
}
}
- 增强类
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterLog implements AfterReturningAdvice{
//returnValue: 返回值
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了" + method.getName() + "方法, 返回结果为:" + returnValue);
}
}
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforLog implements MethodBeforeAdvice{
//method: 要执行的目标对象的方法
//args: 参数
//target: 目标
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "方法被执行了!!!!");
}
}
- 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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册bean -->
<bean id="userService" class="com.ljs.service.UserServiceImpl"/>
<bean id="beforLog" class="com.ljs.log.BeforLog"/>
<bean id="afterLog" class="com.ljs.log.AfterLog"/>
<!-- 方式一: 使用原生的Spring API接口 -->
<!-- 配置aop: 需要导入aop的约束 -->
<aop:config>
<!-- 切入点: expression:表达式.execution(要执行的位置! * * * *) -->
<aop:pointcut id="pointcut1" expression="execution(* com.ljs.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加 -->
<aop:advisor pointcut-ref="pointcut1" advice-ref="beforLog"/>
<aop:advisor pointcut-ref="pointcut1" advice-ref="afterLog"/>
</aop:config>
</beans>
- 测试类
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ljs.service.UserService;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService user = (UserService) context.getBean("userService");
user.add();
}
}
测试结果:
com.ljs.service.UserServiceImpl的add方法被执行了!!!!
add one --------
执行了add方法, 返回结果为:null
方式二: 自定义实现
- 自定类
package com.ljs.diy;
public class DIYService {
public void before() {
System.out.println("=========执行方法前===========");
}
public void after() {
System.out.println("------执行方法后--------");
}
}
- 配置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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册bean -->
<bean id="userService" class="com.ljs.service.UserServiceImpl"/>
<bean id="beforLog" class="com.ljs.log.BeforLog"/>
<bean id="afterLog" class="com.ljs.log.AfterLog"/>
<!-- 方式二: 自定义类 -->
<bean id="diy" class="com.ljs.diy.DIYService"/>
<aop:config>
<!-- 自定义切面, ref 要引用的类 -->
<aop:aspect ref="diy">
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.ljs.service.UserServiceImpl.*(..))" id="point"/>
<!-- 通知 -->
<aop:before method="befor()" pointcut-ref="point"/>
<aop:before method="after()" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
</beans>
- 其他与方式一相同
测试结果:
=========执行方法前===========
add one --------
------执行方法后--------
方式三:使用注解实现
- 定义切面的类
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect//标识这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.ljs.service.UserServiceImpl.*(..))")
public void before() {
System.out.println("--=-=-=-=-=方法执行前-=------=--=-==-");
}
@After("execution(* com.ljs.service.UserServiceImpl.*(..))")
public void after() {
System.out.println("--=-=-=-=-=方法执行后后-=------=--=-==-");
}
@Around("execution(* com.ljs.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("=====环绕前====");
pj.proceed();//方法执行
System.out.println("=====环绕后====");
}
}
- 配置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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册bean -->
<bean id="userService" class="com.ljs.service.UserServiceImpl"/>
<bean id="beforLog" class="com.ljs.log.BeforLog"/>
<bean id="afterLog" class="com.ljs.log.AfterLog"/>
<!-- 方式三: -->
<bean id="annotationPointCut" class="com.ljs.diy.AnnotationPointCut"/>
<!-- 开启注解支持 --><!-- JDK(默认 proxy-target-class="false") cglib(proxy-target-class="true") -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
- 其他与方式一相同
测试结果:
=========执行方法前===========
add one --------
------执行方法后--------
12. 整合Mybatis
步骤:
-
导入相关jar包
- Junit
- mybatis
- mysql数据库
- spring相关的
- aop织入
- mybatis-config [new]
12.1 回忆mybatis
- 编写实体类
public class User {
private int id;
private String name;
private String pwd;
}
- 编写核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.ljs.pojo"/>
</typeAliases>
<environments default="development"><!-- 环境配置:development开发; test测试 -->
<environment id="development">
<transactionManager type="JDBC"/><!-- 配置事务管理方式:JDBC/MANAGED -->
<dataSource type="POOLED"><!-- 配置数据源,即连接池 JNDI已过时 /POOLED:使用连接池(推荐)/UNPOOLED:不使用连接池 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/ljs/mapper/UserMapper.xml"/>
</mappers>
</configuration>
- 编写接口
public interface UserMapper {
public List<User> selectUser();
}
- 编写Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ljs.mapper.UserMapper">
<select id="selectUser" resultType="User">
select * from User
</select>
</mapper>
- 测试
@Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = factory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.selectUser();
for (User user : list) {
System.out.println(user.toString());
}
}
12.2 Mybatis-spring
- 编写数据源配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- DadaSource: 使用Spring的数据源替换Mybatis的配置 c3p0 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root123"></property>
</bean>
</beans>
- sqlSessionfactory
<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /><!-- 数据源 -->
<!-- 绑定Mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- <property name="mapperLocations" value="classpath:com/ljs/mapper/UserMapper.xml" /> -->
<property name="mapperLocations" value="classpath:com/ljs/mapper/*.xml" />
</bean>
- sqlSessionTemplate
<!--SqlSessionTemplate:就是我们使用的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" >
<!-- 只能使用构造器注入sqlSessionFactory, 因为他没有set方法 -->
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
</bean>
- 需要给接口加实现类
public class UserMapperImpl implements UserMapper{
//我们使用的所有操作,都是用sqlSession来执行, 在原来, 现在都使用SqlSessionTemplate;
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
// TODO Auto-generated method stub
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
- 将自己写的实现类注入到Spring中, 配置applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 引用Spring配置文件(配置数据源,sqlSessionFactory, sqlSession) -->
<import resource="spring-dao.xml"/>
<!-- -->
<bean id="userMapper" class="com.ljs.mapper.UserMapperImpl" >
<property name="sqlSession" ref="sqlSession"></property>
</bean>
</beans>
- 测试
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper mapper = context.getBean("userMapper", UserMapper.class);
List<User> list = mapper.selectUser();
for (User user : list) {
System.out.println(user.toString());
}
}
13. 声明式事务
13.1 回顾事务
- 把一组业务当成一个业务来做,要么成功,要么失败!
- 事务在项目假发中涉及到数据的一致性和完整性;
事务ACID原则:
- 原子性
- 一致性
- 隔离性
- 多个业务可能操作同一个资源,防止数据损坏
- 持久性
- 事务一旦提交,无论系统发生什么, 结果都不会被影响, 被持久化到储存器中!
13.2 spring中的事务管理
- 声明式事务: AOP
- 编程式事务: 需要在代码中, 进行事务的管理;(由于要对代码进行 修改,故很少这样做)
声明式事务: 使用AOP方式进行实现
步骤:
- 配置声明式事务:
<!-- 配置声明式事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" name="dataSource" />
</bean>
- 配置事务的通知
<!-- 结合AOP实现事务的织入 -->
<!-- 配置事务的通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 给哪些方法上事务 -->
<tx:attributes>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="insert" propagation="REQUIRED"/>
<tx:method name="select" propagation="REQUIRED"/>
<!-- 给所有的方法上事务 -->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
- 配置事务切入
<!-- 配置事务切入 -->
<aop:config>
<aop:pointcut expression="execution(* com.ljs.mapper.*.*(..))" id="txpointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txpointcut"/>
</aop:config>
- 测试类
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper usermapper = context.getBean("userMapper", UserMapper.class);
List<User> list = usermapper.selectUser();
for (User user : list) {
System.out.println(user);
}
}
为什么需要事务:
- 如果不配置事务, 可能存在数据提交不一致的情况;
- 如果我们不在Spring中去配置声明式事务, 我们就需要早代码中手动配置事务!
- 事务在项目开发中十分重要! 涉及到数据的一致性和完整性!
此文章学习的是狂神说java中Spring,感谢狂神!