概述
文章目录
- Spring概念
- IOC
- 1.IOC底层原理
- 2.IOC接口(BeanFactory)
- 3.IOC操作Bean管理(基于xml配置文件方式实现)
- 4.IOC操作Bean管理(基于注解方式实现)
- AOP
- 1.概念
- 2.AOP底层原理
- 3.AOP-操作术语
- 4.AOP操作
- JdbcTemplate
- 1.概念和准备
- 2.JdbcTemplate操作数据库
- 事务管理
- 1.事务的概念
- 2.搭建事务操作环境
- 3.Spring事务管理介绍
- Spring5新特性
Spring概念
1)Spring是轻量级的开源的JavaEE框架
2)Spring可以解决企业应用开发的复杂性
3)Spring有两个核心部分:IOC和AOP
①IOC:控制反转,把创建对象过程交给Spring进行管理
②AOP:面向切面,不修改源代码进行功能增强
4)Spring特点
①方便解耦,简化开发
②AOP编程支持
③方便程序测试
④方便和其他框架进行整合
⑤方便进行事务操作
⑥降低API开发难度
IOC
1.IOC底层原理
1)xml解析、工厂模式、反射
2)IOC过程
第一步 xml配置文件,配置创建的对象
< bean id=“dao” class=“com.zty.UserDao” >< /bean > 进一步降低耦合
第二步 有service类和dao类,创建工厂类
class UserFactory{
public static UserDao getDao(){
String classValue = class属性值; // 1 xml解析
Class clazz = Class.forName(classValue); 2 通过反射创建对象
return (UserDao)clazz.newInstance();
}
}
3)IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
Spring提供IOC容器实现两种方式:(两个接口)
①BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用,加载配置文件时不会创建文件,在使用对象时才取创建对象
②ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般面向开发人员进行使用,在加载配置文件的时候就会把配置文件对象进行创建
4)ApplicationContext接口有实现类
- FileSystemXmlApplicationContext
- ClassPathXmlApplicationContext
2.IOC接口(BeanFactory)
3.IOC操作Bean管理(基于xml配置文件方式实现)
1)什么是Bean管理
①Spring创建对象
②Spring注入属性
2)创建对象
< bean id=“user” class=“com.zty.spring5.User” > < /bean >
①在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
②在bean标签中有很多属性,介绍常用的属性
id属性:唯一标识
class属性:类全路径(包类路径)
③创建对象时,默认也是执行无参数构造方法完成对象创建
3)注入属性
DI:依赖注入,就是注入属性
第一种注入方式:set方法注入
public void setName(String bname){
this.name = bname;
}
< bean id=“user” class=“com.zty.spring5.User” >
< property name=“bname” value=“易筋经” >< /property >
< property name=“bauthor” value=“达摩老祖” >< /property >
< /bean >
第二种注入方式:有参数构造注入
public Orders(String oname,String address){
this.oname = oname;
this.address = address;
}
< bean id=“orders” class=“com.zty.spring5.Orders” >
< constructor-arg name=“oname” value=“电脑” >< /constructor-arg >
< constructor-arg name=“address” value=“China” >< /constructor-arg >
< /bean >
4)注入其他类型属性
①字面量
- null值
< property name=“address” >
< null/ >
< /property >
- 属性值包含特殊符号
< property name=“address” >
< value > < ![CDATA[<<南京>>]] > < /value >
< /property >
②注入属性-外部bean
- 创建两个类service类和dao类
- 在service调用dao里面的方法
- 在spring配置文件中进行配置
< bean id=“userService” class=“com.zty.spring5.service.UserService” >
< !-- 注入userDao对象
name属性:类里面属性名称
ref属性:创建userDao对象bean标签id值
-->
< property name=“userDao” ref=“userDaoImpl” > < /property >
< /bean >
< bean id=“userDaoImpl” class=“com.zty.spring5.dao.UserDaoImpl” > < /bean >
③注入属性-内部bean
一对多关系:部门和员工
在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
在spring文件中进行配置
< bean id=“emp” class=“com.zty.spring5.bean.Emp” >
< !-- 设置两个普通属性 – >
< property name=“ename” value=“lucy” > < /property >
< property name=“gender” value=“女” > < /property >
< !-- 设置对象类型属性 – >
< property name=“dept” >
< bean id=“dept” class=“com.zty.spring5.bean.Dept” >
< property name=“dname” value=“安保部” > < /property >
< /bean >
< /property >
< /bean >
④注入属性-级联赋值
- 第一种写法
< bean id=“emp” class=“com.zty.spring5.bean.Emp” >
< !-- 设置两个普通属性 – >
< property name=“ename” value=“lucy” > < /property >
< property name=“gender” value=“女” > < /property >
< !-- 级联赋值 – >
< property name=“dept” ref=“dept” > < /property >
< /bean >
< bean id=“dept” class=“com.zty.spring5.bean.Dept” >
< property name=“dname” value=“财务部” > < /property >
< /bean >
- 第二种写法
需要生成dept的get方法
< bean id=“emp” class=“com.zty.spring5.bean.Emp” >
< !-- 设置两个普通属性 – >
< property name=“ename” value=“lucy” > < /property >
< property name=“gender” value=“女” > < /property >
< !-- 级联赋值 – >
< property name=“dept” ref=“dept” > < /property >
< property name=“dept.dname” value=“技术部” > < /property >
< /bean >
< bean id=“dept” class=“com.zty.spring5.bean.Dept” >
< property name=“dname” value=“财务部” > < /property >
< /bean >
5)注入集合属性
①注入数组类型属性
< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >
< property name=“courses” >
< array >
< value >java课程< /value >
< value >数据库课程< /value >
< /array >
< /property >
< /bean >
②注入List集合类型属性
< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >
< property name=“list” >
< list >
< value >张三< /value >
< value >小三< /value >
< /list >
< /property >
< /bean >
③注入Map集合类型属性
< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >
< property name=“maps” >
< map >
< entry key=“JAVA” value=“java” >< /entry >
< entry key=“PHP” value=“php” >< /entry >
< /map >
< /property >
< /bean >
④在集合里面设置对象类型值
< bean id=“stu” class=“com.zty.spring5.collectiontype.Stu” >
< property name=“courseList” >
< list >
< ref bean=“course1” >< /ref >
< ref bean=“course2” >< /ref >
< /list >
< /property >
< /bean >
< !–创建多个对象-- >
< bean id=“course1” class=“com.zty.spring5.collectiontype.Course” >
< property name=“cname” value=“Spring5框架” >< /property >
< /bean >
< bean id=“course2” class=“com.zty.spring5.collectiontype.Course” >
< property name=“cname” value=“MyBatis框架” >< /property >
< /bean >
⑤把集合注入部分提取出来
在spring配置文件中引入名称空间util
xmlns:util=“http://www.springframework.org/schema/util”
xsi:schemaLocation=“http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd”
< util:list id=“bookList” >
< value >易筋经< /value >
< value >九阴真经< /value >
< value >九阳神功< /value >
< /util:list >
< bean id=“book” class=“com.zty.spring5.collectiontype.Book” >
< property name=“list” ref=“bookList” >< /property >
< /bean >
6)IOC操作Bean管理(FactoryBean)
Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)
普通bean:在配置文件中定义的bean类型就是返回类型
工厂bean:在配置文件中定义的bean类型可以和返回类型不一样
第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean
第二部 实现接口里面的方法,在实现的方法中定义返回的bean类型撒旦大神
7)IOC操作Bean管理(bean作用域)
①在Spring里面,设置创建bean实例是单实例还是多实例
②在Spring里面,默认情况下,创建的bean是单实例对象
③如何设置单实例还是多实例
- 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
- scope属性值
- 第一个值 默认值 singleton 表示是单实例对象
- 第二个值 prototype 表示是多实例对象
- singleton和prototype的区别
- 设置scope值是singleton时,加载spring配置文件时就会创建单实例对象
- 设置scope值是prototype时,在调用getBean方法时创建多实例对象
8)IOC操作Bean管理(bean生命周期)
①通过构造器创建bean实例(无参构造)
②为bean的属性设置值和对其他bean引用(调用set方法)
③把bean的实例传递给bean后置处理器的方法postProcessBeforeInitialization
④调用bean的初始化的方法(需要进行配置)
⑤把bean的实例传递给bean后置处理器的方法postProcessAfterInitialization
⑥bean可以使用了(对象获取到了)
⑦当容器关闭的时候,调用bean销毁的方法(需要进行配置销毁的方法)
9)IOC操作Bean管理(xml自动装配)
自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行装入
< !–实现自动装配
bean标签属性autowire,配置自动装配
autowire属性常用有两个值:
byName根据属性名称注入,注入值bean的id值和类属性名称一样
byType根据属性类型注入
–>
10)IOC操作Bean管理(外部属性文件)
直接配置数据库信息
①配置德鲁伊连接池
②引入德鲁伊连接池依赖jar包
< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“com.mysql.jdbc.Driver” >< /property >
< property name=“url” value=“jdbc:mysql://localhost:3306/userDb” >< /property >
< property name=“username” value=“root” >< /property >
< property name=“password” value=“123456” >< /property >
< /bean >引入外部属性文件配置数据库连接池
①创建外部属性文件,properties格式文件,写数据库信息
②把外部properties属性文件引入到spring配置文件中
- 引入context名称空间
xmlns:context=“http://www.springframework.org/schema/context”
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- 在spring配置文件中使用标签引入外部属性文件
<context:property-placeholder location=“classpath:jdbc.properties” />
< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“ j d b c . d r i v e r " > < / p r o p e r t y > < p r o p e r t y n a m e = " u r l " v a l u e = " {jdbc.driver}" >< /property > < property name="url" value=" jdbc.driver"></property><propertyname="url"value="{jdbc.url}” >< /property >
< property name=“username” value=“ j d b c . u s e r n a m e " > < / p r o p e r t y > < p r o p e r t y n a m e = " p a s s w o r d " v a l u e = " {jdbc.username}" >< /property > < property name="password" value=" jdbc.username"></property><propertyname="password"value="{jdbc.password}” >< /property >
< /bean >
4.IOC操作Bean管理(基于注解方式实现)
1)什么是注解
①注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…)
②注解作用在类上面,方法上面,属性上面
③使用注解的目的:简化xml配置
2)Spring针对Bean管理中的创建对象提供注解
① @Component
② @Service
③ @Controller
④ @Respository
*上面四个注解的功能是一样的,都可以用来创建bean实例
3)基于注解方式实现对象创建
①引入依赖spring-aop.jar
②开启组件扫描(之前要引入名称空间context)
< context:component-scan base-package=“com.zty.spring5.service,com.zty.spring5.dao” >< /context:component-scan >
若要扫描多个包,多个包使用逗号隔开也可以扫描包的上层目录
③创建类,在类上面添加创建对象的注解
@Component(value=“userService”) //< bean id=“userService” class=“…” >
value属性值可以省略不写,默认值是类名称,首字母小写
④开启组件扫描细节配置
示例1
< context:component-scan base-package=“com.zty.spring5” use-default-filters=“false” >
< context:include-filter type=“annotation”
expression=“org.springframework.stereotype.Controller”/ >
< /context:component-scan >
use-default-filters="false"表示现在不使用默认filter,自己配置filter
context:include-filter设置扫描哪些内容
示例2
< context:component-scan base-package=“com.zty.spring5” >
< context:exclude-filter type=“annotation”
expression=“org.springframework.stereotype.Controller”/ >
< /context:component-scan >
context:exclude-filter设置哪些内容不进行扫描
4)基于注解方式实现属性注入
@AutoWired:根据属性类型进行自动装配
①把service和dao对象创建,在service和dao类添加创建对象注解
②在service中注入dao对象,在service类添加dao类型属性,不需要添加set方法,在属性上面使用注解
@Qualifier:根据属性名称进行注入
要和@AutoWired一起使用
@Qualifier(value=“userDaoImpl”) 区分哪个对象
@Resource:可以根据类型注入,也可以根据名称注入
根据类型注入:@Resource
根据名称注入:@Resource(name=“userDaoImpl”)
@Value:注入普通类型属性
@Value(value=“abc”)
5)完全注解开发
①创建配置类,替代xml配置文件
@Configuration
@ComponentScan(basePackages={“com.zty”})
public class SpringConfig{}
②编写测试类
/* ApplicationContext context = new ClassPathXmlApplicationContext(“bean1.xml”); */
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean(“userService”,UserService.class);
System.out.println(userService);
userService.add();
AOP
1.概念
1)什么是AOP
①面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了程序的开发效率。
②通俗描述:不通过修改源代码方式,只在主干功能里面添加新功能
③具体举例
2.AOP底层原理
1)AOP底层使用动态代理
有两种情况动态代理
第一种 有接口情况,使用JDK动态代理
创建接口实现类的代理对象,增强类的方法
第二种 没有接口情况,使用CGLIB动态代理
创建子类的代理对象,增强类的方法
3.AOP-操作术语
1)连接点
类里面哪些方法可以被增强,这些方法就叫连接点
2)切入点
实际被真正增强的方法,称为切入点
3)通知(增强)
实际增强的逻辑部分称为通知(增强)
通知有多种类型,包括前置通知、后置通知、环绕通知、异常通知、最终通知(finally)
4)切面(是动作)
把通知应用到切入点的过程
4.AOP操作
1)Spring框架一般都是基于AspectJ实现AOP操作
AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作
2)基于AspectJ实现AOP操作
基于xml配置文件实现
①创建两个类,增强类和被增强类,创建方法
②在spring配置文件中创建两个类对象
< bean id=“book” class=“com.zty.spring5.aopxml.Book” >< /bean >
< bean id=“bookProxy” class=“com.zty.spring5.aopxml.BookProxy” >< /bean >
③在spring配置文件中配置切入点
< aop:config >
< aop:pointcut id=“p” expression=“execution(* com.zty.spring5.aopxml.Book.buy(…))”/ >
< aop:aspect ref=“bookProxy”>
< aop:before method=“before” pointcut-ref=“p”/ >
< /aop:aspect >
< /aop:config >
基于注解方式实现(一般实际用这种方式)
①创建类,在类里面定义方法
public class User {
public void add(){
System.out.println(“add…”);
}
}
②创建增强类(编写增强逻辑)
在增强类里面创建方法,让不同方法代表不同的通知类型
public class UserProxy {
public void before(){
System.out.println(“before…”);
}
}
③进行通知的配置
引入名称空间context和aop
在spring配置文件中,开启注解扫描
< context:component-scan base-package=“com.zty.spring5.aopanno” >< /context:component-scan >
使用注解创建User和UserProxy对象
@Component
在增强类上面添加注解@Aspect
在spring配置文件中开启生成代理对象
< aop:aspectj-autoproxy >< /aop:aspectj-autoproxy >
④配置不同类型的通知
在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
前置通知@Before(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
后置通知(返回通知)@AfterReturning(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
最终通知@After(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
异常通知@AfterThrowing(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
环绕通知@Around(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
⑤相同的切入点抽取
@Pointcut(value=“execution(* com.zty.spring5.aopanno.User.add(…))”)
public void pointdemo(){}
@Before(value=“pointdemo”)
⑥有多个增强类对同一个方法进行增强,设置增强优先级
在增强类上面添加注解@Order(数字类型值),数字类型值越小优先值越高
3)在项目工程里面引入AOP相关依赖
4)切入点表达式
①作用:知道对哪个类里面的哪个方法进行增强
②语法结构:
execution( [权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]) )
JdbcTemplate
1.概念和准备
1)概念
Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库的操作
2)准备工作
①引入相关jar包
②在spring配置文件中配置数据库连接池
< bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource” >
< property name=“driverClassName” value=“com.mysql.jdbc.Driver” >< /property >
< property name=“url” value=“jdbc:mysql://localhost:3306/userDb” >< /property >
< property name=“username” value=“root” >< /property >
< property name=“password” value=“123456” >< /property >
< /bean >③配置JdbcTemplate对象,注入DataSource
< bean id=“jdbcTemplate” class=“org.springframework.jdbc.core.JdbcTemplate” >
< property name=“dataSource” ref=“dataSource” >< /property >
< /bean >
④创建service类,创建dao类,在dao中注入jdbcTemplate对象
2.JdbcTemplate操作数据库
1)添加、修改和删除
①对应数据库表创建实体类
②在dao中进行数据库添加操作
调用JdbcTemplate对象里面update方法实现添加操作
update(String sql,Object… args)
第一个参数:sql语句
第二个参数:可变参数,设置sql语句值
@Override
public void delete(String id){
String sql = “delete from t_book where user_id=?”;
int update = jdbcTemplate update(sql,id);
System.out.println(update);
}
2)查询
返回某个值
@Override
public int selectCount( ){
String sql = "select count(*)from t_book ";
Integer count = jdbcTemplate.queryForObject(sql,Integer.class);
return conunt;
}
返回某个对象
第一个参数:sql语句
第二个参数:RowMapper,是接口,针对返回不同类型的数据,使用这个接口里面的实现类完成数据封装
第三个参数:sql语句值
@Override
public Book findBookInfo(String id){
String sql = “select * from t_book where user_id=?”;
jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper< Book >(Book.class),id);
return Book;
}
返回某个集合
场景:查询图书列表分页
@Override
public List< Book > findAllBook(){
String sql = “select * from t_book”;
List< Book > bookList = jdbcTemplate.query(sql,new BeanPropertyRowMapper< Book >(Book.class));
return bookList;
}
3)批量操作(操作表里面的多条记录)
batchUpdate(String sql,List< Object[] >batchArgs)
第一个参数:sql语句
第二个参数:List集合,添加多条记录的数据
批量添加操作
@Override
public void batchAddBook(List< Object[] >batchArgs){
String sql = “insert into t_book values(?,?,?)”;
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Array.toString(ints));
}
批量修改操作
@Override
public void batchUpdateBook(List< Object[] >batchArgs){
String sql = “update t_book set username = ?,ustatus = ? where user_id = ?”;
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Array.toString(ints));
}
批量删除操作
@Override
public void batchDeleteBook(List< Object[] >batchArgs){
String sql = “delete from t_book where user_id = ?”;
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Array.toString(ints));
}
事务管理
1.事务的概念
1)事务是数据库操作最基本的单元,逻辑上的一组操作,要么都成功,要么都失败
典型场景:银行转账
2)事务的四大特性(ACID)
①原子性 ②一致性 ③持续性 ④隔离性
2.搭建事务操作环境
①创建数据库表,添加记录
②创建service,搭建dao,完成对象注入和注入关系,service注入dao,在dao中注入JdbcTemplate,在JdbcTemplate中注入DataSource
③在dao中创建两个方法:多钱和少钱的方法,在service中创建转账的方法
@Override
public void reduceMoney( ){
String sql = “update t_account set money = money - ? where username = ?”;
jdbcTemplate.update(sql,100,“lucy”);
}
@Override
public void addMoney( ){
String sql = “update t_account set money = money + ? where username = ?”;
jdbcTemplate.update(sql,100,“mary”);
}
public void accountMoney( ){
userDao.reduceMoney();
userDao.addMoney();
}
3.Spring事务管理介绍
1)事务添加到JavaEE三层结构中的service层(业务逻辑层)
2)在Spring中进行事务管理操作
有两种方式:编程式事务管理和声明式事务管理
3)声明式事务管理
事务参数
- propagation:事务传播行为
当一个事务被另外一个事务方法调用的时候,这个事务方法如何进行
REQUIRED:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行
REQUIRED_NEW:当前的方法必须启动新事务,并在它自己的事务内运行,如果有事务正在运行,应该将它挂起
SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
- ioslation:事务隔离级别
事务中有一种特性称为隔离性,多事务操作之间不会产生影响,不考虑隔离性会产生很多问题
三个读问题:脏读、不可重复读、幻读
脏读:一个未提交事务读取到另一个未提交事务的数据
不可重复读:一个未提交事务读取到另一提交事务的修改数据
幻读:一个未提交事务读取到另一提交事务的添加数据
通过设置事务的隔离级别来解决读问题
脏读 不可重复读 幻读 READ UNCOMMITTED(读未提交) 有 有 有 READ COMMITTED(读已提交) 无 有 有 REPEATABLE READ(可重复读) 无 无 无 SERIALIZABLE(串行化) 无 无 无
- timeout:超时时间
事务需要在一定的时间内进行提交,如果不提交需要进行回滚
默认值是-1,设置时间以秒为单位进行计算
- readOnly:是否只读
readOnly默认值false,表示可以查询,可以添加修改删除操作
设置为true后只能进行查询操作
- rollbackFor:回滚
设置出现哪些异常进行事务回滚
- noRollbackFor:不回滚
设置出现哪些异常不进行事务回滚
基于注解方式
①在spring配置文件中配置事务管理器
< !-- 创建事务管理器 -->
< bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager” >
< !-- 注入数据源 -->
< property name=“dataSource” ref=“dataSource” >< /property >
< /bean >②在spring配置文件中引入名称空间tx
< !-- 开启事务注解 -->
< tx:annotation-driven transaction-manager=“transactionManager” >< /tx:annotation-driven >
③在service类上面(获取service类里面的方法上面)添加事务注解
@Transactional
添加到类上表明这个类里面所有的方法都添加了事务
添加到方法上则只为这个方法添加事务
基于xml配置文件方式
在spring配置文件中进行配置
①配置事务管理器
< !-- 创建事务管理器 -->
< bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager” >
< !-- 注入数据源 -->
< property name=“dataSource” ref=“dataSource” >< /property >
< /bean >②配置通知
< tx:advice id=“txadvice” >
< !-- 配置事务参数 -->
< tx:attributes >
< !-- 指定哪种规则的方法上面添加事务 -->
< tx:method name=“accountMoney” propagation=“REQUIRED”/ >
< tx:method name=“account*”/ >
< /tx:attributes >
< /tx:advice >
③配置切入点和切面
< aop:config >
< !-- 配置切入点 -->
< aop:pointcut id=“pt” expression=“execution(* com.zty.spring5.service.UserService.*(…))” >
< !-- 配置切面 -->
< aop:advisor advice-ref=“txadvice” pointcut-ref=“pt”/ >
< /aop:config >
完全注解方式
创建配置类,使用配置类替代xml配置文件
@Configuration //配置类
@ComponentScan(basePackages = “com.zty”) //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig{
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(“”);
dataSource.setUrl(“”);
dataSource.setUsername(“”);
dataSource.setPassword(“”);
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
//到IOC容器中根据类型找到dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器对象
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
4)在Spring中进行声明式事务管理,底层使用AOP原理
5)Spring事务管理API
提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
Spring5新特性
1)整个Spring5框架的代码基于Java8实现,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除
2)Spring5框架自带了通用的日志框架
Spring5已经移除Log4JConfigListenter,官方建议使用Log4j2
Spring5框架整合Log4j2
①引入jar包
②创建Log4j2.xml配置文件(名字固定)
3)Spring5框架核心容器支持@Nullable注解
@Nullable注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数值可以为空
4)Spring5核心容器支持函数式风格GenericApplicationContext
函数式风格创建对象,交给spring进行管理
5)Spring5支持整合JUnit5
整合JUnit4
①引入Spring相关针对测试的依赖
②创建测试类,使用注解方式完成
@RunWith(SpringJUnit4ClassRunner.class) //单元测试框架
@ContextConfiguration(“classpath:bean1.xml”) //加载配置文件
public class JTest4{
@Autowired
private UserService userService;
@Test
public void test1(){
userService.accountMoney();
}
}
整合JUnit5
①引入JUint5的jar包
②创建测试类,使用注解方式完成
@ExtendWith(SpringExtension.class)
@ContextConfiguration(“classpath:bean1.xml”)
//也可使用@SpringJUintConfig(locations=“classpath:bean1.xml”)代替上边两个注解
public class JTest5{
@Autowired
private UserService userService;
@Test
public void test1(){
userService.accountMoney();
}
}
6)SpringWebFlux
①SpringWebFlux介绍
是Spring5添加的新的模块,用于web开发的,功能SpringMVC类似的,WebFlux是使用当前一种比较流行的响应式编程而出现的框架
使用传统Web框架,比如SpringMVC,这些是基于Servlet容器,WebFlux是一种异步非阻塞的框架,异步非阻塞的框架在Servlet3.1以后才支持,核心是基于Reator的相关API实现的
异步和同步针对调用者,调用者发出请求,如果等着对方回应之后才去做其他事情就是同步,如果发送请求之后不等着对方回应就去做其他事情就是异步
阻塞和非阻塞针对被调用者,被调用者收到请求之后,做完请求之后才给出反馈就是阻塞,收到请求之后马上给出反馈再去做事情就是非阻塞
WebFlux特点
第一:非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程
第二:函数式编程:Spring5框架基于java8,WebFlux使用Java8函数式编程方式实现路由请求
比较SpringMVC和SpringWebFlux
第一:两个框架都可以使用注解方式,都运行在Tomcat等容器中
第二:SpringMVC采用命令式编程,WebFlux采用异步响应式编程
②响应式编程
响应式编程是一种面向数据流和变化传播的编程范式,这意味着可以在编程语言中很方便地表达静态或动态的数据流,而计算机相关模型会自动将变化的值通过数据流进行传播
响应式编程操作中,Reactor是满足Reactive规范的框架
Reactor有两个核心类,Mono和Flux,这两个类都实现了接口Publisher,它提供了丰富的操作符。Flux对象实现发布者,返回N个元素;Mono实现发布者,返回0或者1个元素
Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信号:元素值、错误信号、完成信号。其中错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者
三种信号的特点:
错误信号和完成信号都是终止信号,不能共存的
如果没有发送任何元素值,而是直接发送错误信号或者完成信号,表示是空数据流
如果没有错误信号,没有完成信号,表示是无限数据流
操作符:对数据流进行一道道操作,称为操作符,比如工厂流水线
第一:map元素映射为新元素
第二:flatMap元素映射为流。把每个元素转换成流,把转换之后的多个流合并成大的流
③WebFlux执行流程和核心API
SpringWebFlux基于Reactor,默认使用容器是Netty,Netty是高性能的NIO框架,异步非阻塞的框架
SpringWebFlux执行过程和SpringMVC是相似的
SpringWebFlux核心控制器DispatchHandle:,实现接口WebHandler,负责请求的处理
HandlerMapping:请求查询到处理的方法
HandlerAdapter:真正负责请求处理
HandlerResultHandler:响应结果处理
SpringMVC方式实现,同步阻塞的方式,基于SpringMVC+Servlet+Tomcat
SpringWebFlux方式实现,异步非阻塞方式,基于SpringWebFlux+Reactor+Netty
④SpringWebFlux(基于注解编程模型)
⑤SpringWebFlux(基于函数式编程模型)
在使用函数式编程模型操作的时候,需要自己初始化服务器
SpringWebFlux实现函数式编程,两个核心接口:RouterFunction(实现路由功能,请求转发给对应的handler)和HandlerFunction(处理请求生成响应的函数)
核心任务就是定义两个函数式接口的实现并且启动需要的服务器
SpringWebFlux请求和响应不再是ServletRequest和ServletResponse,而是ServerRequest和ServerResponse
最后
以上就是单薄发带为你收集整理的Spring5学习笔记的全部内容,希望文章能够帮你解决Spring5学习笔记所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复