spring框架
概述
- 轻量级的开源框架
- 两个核心IOC和AOP
- IOC创建对象交给Spring
- 面向切面,不改源码来修改功能
- 特点
- 简化
- 方便事务
- 降低api难度
- 支持aop编程
- 方便与其他框架进行整合
入门
-
导包
-
创建对象
- 通过配置文件
<?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">
<!--创建User对象 -->
<bean id="user" class="com.spring5.User">
//id表示唯一标识,class表示包类路径
</bean>
</beans>
---------------------------
@Test//就可以了
public void test(){
//1.加载配置文件
ApplicationContext context= new ClassPathXmlApplicationContext("bean02.xml");
//2.获取配置的创建对象
User user = context.getBean("user",User.class);
System.out.println(user);
user.method();
}
IOC—》控制反转
原理(xml解析,工厂模式,反射)
工厂模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ShXK7Wq-1646304849602)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220227153104091.png)]
加反射,xml解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOeukSuQ-1646304849603)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220227154138885.png)]
接口
ioc底层是对象工厂
BeanFactory:
Spring内部的使用接口,不提供开发人员使用,加载配置文件,不会创建对象。
ApplicationContext:
面向开发人员,加载配置文件,就会创建对象。
ApplicationContext实现类
FileSystemXmlApplicationConText//绝对路径
ClassPath…//相对路径
Bean管理
创建对象
注入属性
基于xml创建对象和注入属性
创建对象:
bean标签来配置,创建对象,会默认执行无参构造。
注入属性:
DI(依赖注入),使用set方法注入,还有一种是用
有参构造来注入。
set注入如下:
//先配置xml,来创建一个对象,在注入数据
<bean id="book" class="com.spring5.Book">
<property name="name" value="笑傲江湖"></property>
<property name="author" value="达摩"></property>
</bean>
//Bean数据
public class Book {
private String name;
private String author;
public void setName(String name) {
this.name = name;
}
public void setAuthor(String author) {
this.author = author;
}
public void bookMmethod(){
System.out.println("书名是:" + name + "\n作者是:" + author);
}
}
//测试类
@Test
public void booktest(){
//1.加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean02.xml");
//2.获取配置创建的对象
Book bookd= context.getBean("book",Book.class);
System.out.println(bookd);
bookd.bookMmethod();
}
有参构造来实现:
//javaBean
class A{
private String username;
private String password;
public void A(Stirng name,String password){
this.username =username;
this.password = password;
}
}
//bean02.xml配置
<bean id="A",class="包路径.A">
<constructor-arg name="username" value="王大锤"></constructor-arg>
<constructor-arg name="password" value="123"></constructor-arg>
</bean>
//测试类
@Test
public void test(){
//1.加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean02.xml");
//2.获取配置创建的对象
A a = context.getBean("A",A.class);
System.out.println(ad);
}
xml注入其他符号
特殊符号如:<<南京>>
<![CDATA[<<南京>>]]>
空值:
注入属性-外部Bean:
//service类,dao类,如何在service里注入dao对象
xml配置
//service对象的创建
<bean id="service" class="包路径.类名">
//注入dao对象,service里面要实例个dao对象
<property name ="dao" ref="daoImpl"></property>
//创建一个dao对象,id
<bean id="daoImpl" class="包路径.类名"></bean>
</bean>
注入属性-内部bean和级联赋值
//内部Bean
//service类,dao类,如何在service里注入dao对象
xml配置
//service对象的创建
<bean id="service" class="包路径.类名">
//注入dao对象,
<property name ="dao" >
<bean id="dao" class="包路径.类名">
< property name="service" value="值" ></property>
</bean>
</property>
</bean>
</bean>
//级联赋值
同外部Bean
注入集合
<bean id="Stu" class="包路径.类名">
//注入数组
<property name="arr">
<array>
<value>javascript</value>
<value>c++</value>
</array>
</property>
//注入List集合
<property name="list" >
<list>
<value>1 </value>、
<value>2 </value>
</list>
</property>
//注入map集合
<property name="map">
<map>
<entry key="1"value="a"></entry>
<entry key="2"value="g"></entry>
</map>
//注入set集合
</property>
<property name="set">
<set>
<value>2</value>
</set>
</property>
</bean>
//集合里注入对象
//注入List集合
<property name="list" >
<list>
<ref bean="courese1"> </ref>
<ref bean="course2"></ref>
</list>
</property>
<bean id ="courde1" class="类名">
<property name="coures" value="spring"></property>
</bean>
<bean id ="courde2" class="类名">
<property name="coures" value="mybatis"></property>
</bean>
Bean管理之FactoryBean
工厂bean:在配置文件定义bean类型可以和返回类型不一样
第一步创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步实现接口里面的方法,在实现的方法中定义返回的bean类型。
//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">
<bean id="course" class="com.spring5.Course"></bean>
</beans>
-----------------------------------
//创建一个类,实现FactoryBean类,第一个方法就是改变返回对象的
package com.spring5;
import org.springframework.beans.factory.FactoryBean;
public class Course implements FactoryBean <Course>{
@Override
public Course getObject() throws Exception {
Course course = new Course();
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
==============================================
//测试方法
@Test
public void factorybeantest(){
//1.加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
//2.获取配置创建的对象
Course bookd= context.getBean("course", Course.class);
System.out.println(bookd);
}
Bean管理之Bean作用域
1、在 Spring里面,设置创建bean实例是单实例还是多实例
2、在Spring里面,默认情况下,bean是单实例对象
3、如何设置单实例还是多实例
(1)在spring配置文件 bean标签里面有属性(scope)用于设置单实例还是多实例 scope属性
第一个值默认值,singleton,表示是单实例对象·第二个值prototype,表示是多实例对象
<bean id="book”class="com atguigu. spring5.collectiontype. Book” scope="prototype”>
</ property>
'bean>
com.atguigu. spring5.collectiontype Book@5di1346acom. atguigu. spring5.collectiontype Book@7a36aefa
-
singleton和prototype区别·
第一 singleton单实例,prototype多实例第二设置scope值是singleton时候,加载 spring配置文件时候就会创建单实例对象
设置scope 值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
Bean管理之生命周期
(1)通过构造器创建bean 实例无参数构造。
(2)为bean的属性设置值和对其他bean引用(调用set方法)(3)调用bean的初始化的方法(需要进行配置初始化的方法)(4) bean可以使用了(对象获取到了)
(5)当容器关闭时候,调用bean 的销毁的方法(需要进行配置销毁的方法)
后置处理器:
(1)通过构造器创建bean 实例无参数构造。
(2)为bean的属性设置值和对其他bean引用(调用set方法)
- 把Bean实例传递bean后置处理器的方法
(3)调用bean的初始化的方法(需要进行配置初始化的方法
把Bean实例传递bean后置处理器的方法
(4) bean可以使用了(对象获取到了)
(5)当容器关闭时候,调用bean 的销毁的方法(需要进行配置销毁的方法)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvZA7C3g-1646304849603)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228141659271.png)]
将外部properties文件引入到spring配置文件中
1,引入context名称空间
//创建一个jdbc.properties文件
pro.driveClass=com.mysql.jdbc.Driver
pro.url=jdbc:mysql://localhost:3306/DB
pro.username=root
pro.password=123456
//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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${pro.driveClass}"></property>
<property name="url" value="${pro.url}"></property>
<property name="username" value="${pro.username}"></property>
<property name="password" value="${pro.password}"></property>
</bean>
</beans>
Bean管理基于注解
注解:
@名字(键=值…)
作用于类上面,方法上面,属性上面
简化xml的配置
基于注解创建对象
1,引入spring-AOP-5.2.6-RELease.jar包
2.开启组件扫描
<context:component-scan base-package=“com.spring5”></context:component-scan>
3.创建类
//在注解里面value属性值可以省略不写,
//默认值是类名称,首字母小写
//UserService – userService//
@Component
public class UserService {
public void add( {
System. out. println(“service add… . …”) ;
)
}
基于注解实现属性注入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L15wewx4-1646304849604)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228165049700.png)]
//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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${pro.driveClass}"></property>
<property name="url" value="${pro.url}"></property>
<property name="username" value="${pro.username}"></property>
<property name="password" value="${pro.password}"></property>
</bean>-->
<context:component-scan base-package="com" ></context:component-scan>
</beans>
-------------------------------
//userService
@Service("userService")
public class UserService {
@Autowired
private Userdao userdao;
public void add(){
System.out.println("add...");
userdao.add();
}
}
----------------------------------------------
//UserdaoImpl
@Repository("userDaoImpl")
public class UserdaoImpl implements Userdao{
@Override
public void add() {
System.out.println("UserdaoImpl add()....");
}
}
---------------------------------------------
//Test
@Test
public void AutoText(){
//1.加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
//2.获取配置创建的对象
UserService userService=(UserService) context.getBean("userService");
System.out.println(userService);
userService.add();
}
纯注解开发
1.创建配置类,替代xml配置
@Configuration
@ComponentScan(basePackages = {"com"})
public class SpringConfig {
}
写测试类
public void Test(){
//1.加载配置类
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
//2.获取配置创建的对象
UserService userService=(UserService) context.getBean("userService");
System.out.println(userService);
userService.add();
}
AOP
概念
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X2BWRdAE-1646304849605)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228190907436.png)]
不通过修改源代码来添加功能。
原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vt5jv0wR-1646304849605)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228191441591.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X6nNhtbd-1646304849605)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228191649025.png)]
底层代码实现
//接口
public interface Userdao {
public int add(int a,int b);
public String update(String id);
}
//实现接口类
public class UserdaoImpl implements Userdao{
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public String update(String id) {
return id+1;
}
}
//Proxy增强实现接口类的功能
public class JdkProxy {
public static void main(String[] args) {
UserdaoImpl userdao = new UserdaoImpl();
//创建接口实现类代理对象************
Class[] interfaces = {Userdao.class};
Userdao dao= (Userdao) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces, new UserdaoProxy(userdao));
int add = dao.add(2, 3);
System.out.println(add);
}
}
//创建代理对象
class UserdaoProxy implements InvocationHandler {
//把创建的是谁的代理对象,把谁传过来
//有参构造传递
private Object object;
public UserdaoProxy(Object object){
this.object=object;
}
//增强的逻辑
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("方法之前:" + method.getName() + Arrays.toString(args));
//被增强的方法
Object re = method.invoke(object, args);
//方法之后
System.out.println("方法之后被执行。。");
return re;
}
}
AOP术语
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6cjrG0XZ-1646304849606)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220228202120164.png)]
AOP操作(准备)
1、Spring框架一般都是基于Aspect实现AOP操作(1))什么是 Aspect
2、 AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ,和Spring.框架一起使用,进行AOP操作I
切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构:
execution([权限修饰符] [返回类型] [类余路径] [方法名称] ([参数列表]))
举例1:对com.atguigu.dao.BookDao类里面的add进行增强execution(*Eom.atguigu.dao.BookDao.add(…))
举例2:对 com.atquigu.dao.BookDao类里面的所有的方法进行增强execution(* com.atguigu.dao.BookDao.*(…))
举例3:对com.atguigu.dao包里面所有类,类里面所有方法进行增强
execution(* com.atguigu.dao.* .*(…))
aop实现增强类方法
- 创建类,创建一个方法
- 创建增强类,编写增强逻辑
- 进行通知的配置
@Component
public class User {
public void add(){
System.out.println("add...");
}
}
@Component
@Aspect //生成代理对象
public class UserProxy {
///前置通知
@Before(value = "execution(* com01.proxy.User.add(..))")
public void before(){
System.out.println("before...");
}
//后置通知
@After(value = "execution(* com01.proxy.User.add(..))")
public void After(){
System.out.println("After...");
}
//环绕通知
@Around(value = "execution(* com01.proxy.User.add(..))")
public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("坏绕前...");
proceedingJoinPoint.proceed();
System.out.println("坏绕后...");
}
//最终通知
@AfterReturning(value = "execution(* com01.proxy.User.add(..))")
public void AfterReturning(){
System.out.println("AfterReturning...");
}
//异常通知
@AfterThrowing(value = "execution(* com01.proxy.User.add(..))")
public void AfterThrowing(){
System.out.println("AfterThrowing...");
}
}
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${pro.driveClass}"></property>
<property name="url" value="${pro.url}"></property>
<property name="username" value="${pro.username}"></property>
<property name="password" value="${pro.password}"></property>
</bean>-->
<!--开启注解扫描-->
<context:component-scan base-package="com01.proxy" ></context:component-scan>
<!--开启Apect生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
public class AopTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
User user = context.getBean("user", User.class);
user.add();
}
}//测试类
切入点抽取
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYGxkyky-1646304849606)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301135440004.png)]
**6、**有多个增强类多同一个方法进行增强,设置增强类优先级
在增强类上面添加注解@Order(数字类型值),数字类型值越小优先级越高.
aop配置文件加注解实现增强类
//被增强类
public class Pen {
public void write(){
System.out.println("write...");
}
}
//增强类
public class AopWrite {
public void before(){
System.out.println("brfore...");
}
}
//xml配置
<bean id="pen" class="com01.proxy.Pen"></bean>
<bean id="aopWrite" class="com01.proxy.AopWrite"></bean>
<!--配制aop增强-->
<aop:config>
<!--切入点-->
<aop:pointcut id="a" expression="execution(* com01.proxy.Pen.write())"/>
<!--切入面-->
<aop:aspect ref="aopWrite">
<aop:before method="before" pointcut-ref="a"></aop:before>
</aop:aspect>
</aop:config>
基于上面实现完全注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUc6Id6k-1646304849607)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301142205244.png)]
JdbceTemplate
什么是JdbcTemplate-
Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cz2QHqpy-1646304849608)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301142818596.png)]
2.配置数据库连接,配置JdbcTemplate对象,注入DataSource
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql:///user_db"></property>
<property name="username" value="root"></property>
<property name="password" value="yz"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!--配置jdbcTemplete对象,-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入DateSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</bean
3.创建service类,dao类,在dao注入jdbcTemplate对象
//Service类
@Service
public class BookService {
//注入dao
@Autowired
private BookDao bookDao;
}
//dao类
@Component
public class BookDaoImpl implements BookDao{
//注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
}
增:jdbcTemplate.update()方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Lv4zupn-1646304849608)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301175529985.png)]
查询对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hLAHfjoL-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301180959428.png)]
查询集合
//查询某一个集合的具体方法bookService
public List<Book> findall(){
return bookDao.all();
}
//dao
@Override
public List<Book> all() {
String sql="select * from book";
List<Book> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
return list;
}
//Test
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean03.xml");
BookService bookService = context.getBean("bookService", BookService.class);
Book book = new Book();
List<Book> all = bookService.findall();
System.out.println(all);
}
jdbcTemplate批量增加
//批量增-Service
public void batchadd(List<Object[]> args){
bookDao.batch(args);
}
//dao
@Override
public void batch(List<Object[]> args) {
String sql = "insert into book values(?,?,?)";
int[] ints = jdbcTemplate.batchUpdate(sql, args);
System.out.println(Arrays.toString(ints));
}
//Test
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean03.xml");
BookService bookService = context.getBean("bookService", BookService.class);
Book book = new Book();
List<Object[]> list = new ArrayList<>();
Object[] o1 ={"1","2","3"};
Object[] o2 ={"3","2","3"};
Object[] o3 ={"f","fg","3"};
list.add(o1);
list.add(o3);
list.add(o2);
bookService.batchadd(list);
}
批量修改,删除同上
事务操作
1、什么事务
(1)事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有都失败
(2)典型场景:银行转账
2,特性
原子性
一致性
隔离性
持久性
3,转账案列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2pXxlsr-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220301192834217.png)]
事务的过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJnPPuwu-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302084911882.png)]
Spring事务管理
方式一:编程式管理(繁琐)(略)
方式二:声明式管理(常用)
基于注解事务操作
1、在spring配置文件配置事务管理器
2、在spring配置文件,开启事务注解在spring配置文件引入名称空间tx
3.开启事务注解
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
4.在Service类上加上事务注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-seuookG9-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302091118395.png)]
@Transrctional注解的参数
1.propagetion事务传播行为
7种事务传播行为
REQUIRED
如果add方法本身有事务,调用update方法之后,update使用当前add方法里面事务如果add方法本身没有事务,调用updato方法之后,创建新事务REQUIRED_NEw
使用add方法调用update方法,如果add无论是否有事务,都创建新的事务SUPPORTS
如果有事务在运行,当前的方法就在这个事务内运行.否则它可以不运行在事务中
NOT_SUPPORTE
当前的方法不应该运行在事务中.如果有运行的事务,将它挂起MANDATORY
当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常NEVER
当前的方法不应该运行在事务中.如果有运行的事务,就抛出异常如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运NESTED
行.否则,就启动一个新的事务,并在它自己的事务内运行.
2.ioslation隔离级别
(1)事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题.
有三个读问题:脏读、不可重复读、虚(幻)读
脏读:一个未提交事务读取到另一个未提交事务的数
不可重复读:一个未提交事务读取到另一提交事务修改数据
幻读:一个未提交事务读取到另一提交事务添加数据
解决:mysql默认第三种
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4vsgXnmr-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302093611754.png)]
3.timeout超时时间
(1)事务需要在一定时间内进行提交,如果不提交进行回滚(2)默认值是-1,设置时间以秒单位进行计算
4.readOnly只读
(1)读:查询,写:添加修改删除探作
(2) readOnly,默认值false,表示可以查询,可以添加修改删除操作,(3)设置readOnly值是true,设置成true之后,只能查询
5.、rollbackFor:回滚
设置出现哪些异常进行事务回滚
6.、noRollbackFor:不回滚,
设置出现哪些异常不进行事务回滚。
基于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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">
<!--开启扫描-->
<context:component-scan base-package="com" ></context:component-scan>
<!--连接数据库-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!--url配置需要注意以下-->
<property name="url" value="jdbc:mysql://localhost:3306/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
"></property>
<property name="username" value="root"></property>
<property name="password" value="yz"></property>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
</bean>
<!--配置jdbcTemplete对象,-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入DateSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--创建事务管理器-->
<bean id="dataSourceTransactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置通知-->
<tx:advice id="txadvice">
<tx:attributes>
<tx:method name="accontMoney" propagation="REQUIRED" timeout="5"/>
</tx:attributes>
</tx:advice>
<!--配置切入点和切面-->
<aop:config>
<aop:pointcut id="p" expression="execution(* com.service.UserService.*(..))"/>
<!--切面-->
<aop:advisor advice-ref="txadvice"pointcut-ref="p"></aop:advisor>
</aop:config>
</beans>
完全注解式声明开发
使用配置类,代替xml配置
package com.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
@Configuration//配置类
@ComponentScan(basePackages = "com")//组件扫描
@Transactional()//开启事务
public class TxConfig {//配置类,完全注解开发
//创建数据库连接池
@Bean
public DruidDataSource getDruidDateSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl("jdbc:mysql://localhost:3306/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai");
druidDataSource.setUsername("root");
druidDataSource.setPassword("yz");
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return druidDataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTempalate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//注入dataSouce
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
Test
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pQG0dwXb-1646304849609)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302101720388.png)]
spring5框架新功能
1.Spring 5.0框架自带了通用的日志封装;
(1)Spring5已经移除Log4jConfigListener,官方建议使用Log4j2
.(2) Spring5框架整合Log4j2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eVjyZuWQ-1646304849610)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302103744860.png)]
xml配置(固定)
2.支持@Nullable注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OAYOJvVT-1646304849610)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302104818893.png)]
3.函数式风格创建对象,交给Spring管理
//函数式风格创建对象,交给spring进行管理
@Test
public void testGenericApplicationContext ( {
//1创建GenericApplicationContext对象
GenericApplicationContext context = new GenericApplicationContext() ;
//2调用context的方法对象注册
context.refresh() ;//清空
context.registerBean(User. class, ( -> new UserO);
//3获取在spring注册的对象
User user = (User)context.getBean( name: "com. atguigu. spring5.test.User");
System. out. println(user);
4**.springwebflux**
(1)是Spring5添加新的模块,用于 web 开发的,功能和SpringMIMC类似的,Webflux,使用当前一种比较流程响应式编程出现的框架。
(2)使用传统 web框架,比如SpringMVC,这些基于Servlet,.容器,Webflux,是一种异步非阻塞( 被调用者收到请求之后,马上给出反馈)的框架,异步非阻塞的框架在Servlet3.1以后才支持,核心是基于Reactor的相关API实现的
Webflux特点:
第一非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程.
第二函数式编程:Spring5框架基于java8,Webflux使用Java8函数式编程方式实现路由请求.
springwebflux和spring mvc区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLJqHDBD-1646304849610)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302145245121.png)]
响应式编程:
响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
响应式编程的实现Reactor
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2Sfg5ZG-1646304849610)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302163732461.png)]
Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信号:元素值,错误信号,完成信号,错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sMqPWyGZ-1646304849611)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302164740720.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l94w11DK-1646304849612)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302165002309.png)]
操作符(map,flatmap)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tNkAoHTj-1646304849612)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302165226184.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GwVFHvaN-1646304849612)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302165342697.png)]
SpringWebflux,基于Reactor,默认使用容器是Netty,Netty是高性能的IO框架,异步非阻塞的框架)
Spring执行流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Sawcaod-1646304849612)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302175740729.png)]
基于注解方式编程模型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HYXXHMDG-1646304849613)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302180412489.png)]
基于函数式编程模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZE6Br7Qf-1646304849613)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220302184036502.png)]
tguigu. spring5.test.User");
System. out. println(user);
##### 4**.springwebflux**
(1)是Spring5添加新的模块,用于 web 开发的,功能和SpringMIMC类似的,Webflux,使用当前一种比较流程响应式编程出现的框架。
(2)使用传统 web框架,比如SpringMVC,这些基于Servlet,.容器,Webflux,是一种异步非阻塞( 被调用者收到请求之后,马上给出反馈)的框架,异步非阻塞的框架在Servlet3.1以后才支持,核心是基于Reactor的相关API实现的
Webflux特点:
第一非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程.
第二函数式编程:Spring5框架基于java8,Webflux使用Java8函数式编程方式实现路由请求.
springwebflux和spring mvc区别
[外链图片转存中...(img-mLJqHDBD-1646304849610)]
> 响应式编程:
>
> 响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
响应式编程的实现Reactor
[外链图片转存中...(img-z2Sfg5ZG-1646304849610)]
Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信号:元素值,错误信号,完成信号,错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者。
[外链图片转存中...(img-sMqPWyGZ-1646304849611)]
[外链图片转存中...(img-l94w11DK-1646304849612)]
操作符(map,flatmap)
[外链图片转存中...(img-tNkAoHTj-1646304849612)]
[外链图片转存中...(img-GwVFHvaN-1646304849612)]
SpringWebflux,基于Reactor,默认使用容器是Netty,Netty是高性能的IO框架,异步非阻塞的框架)
Spring执行流程
[外链图片转存中...(img-3Sawcaod-1646304849612)]
> 基于注解方式编程模型:
>
> [外链图片转存中...(img-HYXXHMDG-1646304849613)]
>
> 基于函数式编程模型
>
> [外链图片转存中...(img-ZE6Br7Qf-1646304849613)]
>
>