Spring
- 1.Spring 5简单介绍
- 2.IOC(反转控制)
- 1.什么是IOC
- 2.IOC底层原理
- 3.Bean管理操作的两种方式
- 1--基于xml配置文件方式实现
- (1)注入对象
- (2)注入属性
- 注入属性-外部bean
- 注入属性-内部bean和级联赋值
- 注入集合类型的属性
- 将集合注入部分提取出来
- IOC操作Bean
- IOC操作Bean管理(FactoryBean)
- IOC操作Bean管理(bean作用域)
- IOC操作Bean管理(bean生命周期)
- IOC操作Bean管理(自动装配)
- IOC操作Bean管理(外部属性文件)
- 2--基于Spring注解方式实现
- 1、什么叫注解
- 2、Spring针对Bean管理中创建对象提供注解
- 3、基于Spring注解实现对象的创建
- 4、基于注解的方式实现属性注入
- 5、Spring中的@Bean注解
- spring的注解分类
- @bean注解概述
- 6、完全注解开发
- 1--基于xml配置文件方式实现
- 3.AOP(面向切面编程)
- 1、 什么是AOP
- 2、AOP底层原理
- (1)AOP底层使用动态代理
- (2)AOP(JDK动态代理)
- (3)AOP术语
- (4)AOP操作准备
- (5)AOP操作
- 1、AspectJ注解方式(掌握)
- 2、AspectJ配置文件方式(了解)
- 4、数据库事务、JDBCTemplate
- (1) 简介、测试
- (2)JDBCTemplate操作数据库(增删查改)
- (3)事务操作
- 1.什么是事务?
- 2.事务的特性(ACID)
- 3.事务环境
- 4.事务的操作
- 5.XML声明式事务管理
- 1.在spring配置文件中进行配置
- 2.完全注解声明式
- 5、Spring5框架的新功能
- 1.增加功能
- 2.核心特性
- 3.WebFlux
- (1)简单介绍
- (2)响应式编程
- (3)WebFlux 执行流程和核心API
- (4)SpringWebflux(基于注解编程模型)
- (5)SpringWebflux(基于函数式编程模型)
1.Spring 5简单介绍
1、spring是轻量级的开源的JavaEE框架
2.、Spring可以解决企业应用开发的复杂性
3、Spring有俩个核心部分:IOC和AOP
? (1)IOC:控制反转,把创建对象过程交给Spring进行管理
? (2)AOP:面向切面,不修改源代码进行功能增强
4、Spring特点
(1)方便解耦,简化开发
(2)AOP编程支持
(3)方便Junit测试
(4)方便和其他框架进行整合
(5)方便进行事务操作
(6)降低API开发难度
2.IOC(反转控制)
1.什么是IOC
(1)控制反转,把对象的创建和对象之间调用的过程,交给Spring进行管理
? (2)使用IOC目的:为了降低耦合度
? Spring 核心容器(Core)提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory使用控制反转(Ioc)模式将应用程序的配置和依赖性规范与实际的应用代码程序分开。Spring的声明式事务基于AOP实现,却并不需要程序开发者成为AOP专家,亦可轻易使用Spring的声明式事务管理。
2.IOC底层原理
? (1)xml解析、工厂模式、反射
](javascript:void(0)??
class Yanggb {
@Bean
public YanggbDao createYanggbDaoBean(){
return new YanggbDao();
}
}
[](javascript:void(0)??
在上面的例子中,createYanggbDaoBean方法就会产生一个YanggbDao对象,并将这个对象交给Spring管理(放到ioc容器中)。到这里很容易就能明白,@bean注解是使用在方法上的注解,它会明确地告诉被注解的方法去产生一个bean对象并交给spring容器管理。简单点说就是,@bean注解放在方法上,让方法去产生一个bean交给spring容器。
因为@bean注解是使用在方法上的,因此使用@bean注解的另一个好处就是能够动态获取一个bean对象,且能够根据环境不同得到不同的bean对象。
另外,@bean注解和xml配置中的bean标签的作用是一模一样的。
6、完全注解开发
? (1)创建配置类,代替xml配置文件
//注解类
@Configuration
@ComponentScan(basePackages = {"com.Spring5_demo3"})
public class config {
}
//测试
@Test
public void test()
{
ApplicationContext context = new AnnotationConfigApplicationContext (Config.class);
UserService userService = context.getBean ("userService", UserService.class);
userService.show ();
}
3.AOP(面向切面编程)
1、 什么是AOP
? (1)面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
? (2)通俗来说AOP,就是不通过修改源代码,来增加功能。
?
2、AOP底层原理
(1)AOP底层使用动态代理
? ①有接口的情况,使用JDK动态代理
? ②没有接口的情况,使用CGLIB动态代理
(2)AOP(JDK动态代理)
? ①调用newProxyInstance(ClassLoader loader,类<?> [] interfaces,InvocationHandler h)方法
? 方法有三个参数 :
? 1-类加载器、2-增强方法所在的类,这个类实现的接口,支持多个接口
? 3-实现这个接口InvocationHandler,创建代理对象,写增强的方法
package com.Spring5_demo4.AOP_Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class JDKProxy {
public static void main(String[] args) {
//创建接口实现类代理对象
Class[] interfaces = {UserDao.class};
UserDaoimpl userDao = new UserDaoimpl ();
UserDao dao = (UserDao)Proxy.newProxyInstance (JDKProxy.class.getClassLoader (), interfaces, new UserDaoProxy (userDao));
int addres = dao.add (1, 2);
System.out.println (addres);
}
}
class UserDaoProxy implements InvocationHandler{
//把创建的是谁的代理对象,就将谁传递过来 这里创建的是UserDao的代理对象
private Object obj;
public UserDaoProxy(Object object)
{
this.obj = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前进行处理
System.out.println ("在方法之前执行--"+method.getName ()+"传递的参数:"+ Arrays.toString (args));
//被增强的方法执行
Object res = method.invoke (obj, args); //执行add后返回一个结果
//方法之后
System.out.println ("方法之后执行---"+obj);
return res;
}
}
(3)AOP术语
? 1、连接点
? 2、切入点
? 实际被真正增强的方法,称为切入点;
? 3、通知(增强)
? ①实际增强的逻辑部分称为通知(增强)
? ②通知有五种类型
? 1.前置通知 2.后置通知 3.环绕通知 4.异常通知 5.最终通知
? 4、切面
? 将通知应用到切入点的过程;
(4)AOP操作准备
? 1、Spring 框架一般基于AspectJ实现AOP操作
? AspectJ不是Spring的组成部分,而是独立的AOP框架,一般把AspectJ和Spring框架整合使用,进行AOP操作
? 2、基于AspectJ实现AOP操作
? ①基于xml配置文件方式实现
? ②基于Spring注解方式实现(常用)
? 3、在项目中引入AOP依赖
? 4、切入点表达式
? ①切入点表示式的作用:可以知道对哪个类的哪个方法进行增强
? ②语法结构:execution([权限修饰符] [返回类型] [类全路径] [方法名称] [参数列表])
? 包 . Student .*表示对Student类中的所有方法进行增强
? 包 . * . *表示对包中的所有类的所有方法进行增强
(5)AOP操作
1、AspectJ注解方式(掌握)
? ①编写增强类和被增强类
? 在增强类中,创建方法,让不同方法代表不同通知类型
? ②进行通知的配置
? 1.在Spring配置文件中,开启注解扫描
<?xml version="1.0" encoding="UTF-8"?>
? 2.使用注解创建User和UserProxy对象
? 3.在增强类上面添加注解@Aspect
? 4.在Spring配置文件中开启生成代理对象
? ③配置不同类型的通知
? 在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式来配置
package com.Spring5_AOP_annotation.bean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 增强类
*/
@Component
@Aspect //表示生成代理对象
public class UserProxy {
/**
* 前置通知
* @Before注解就表示前置通知
*/
@Before (value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void before()
{
System.out.println ("before------");
}
/**
* 最终通知 无论有没有异常都会执行
*/
@After (value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void after()
{
System.out.println ("after--------");
}
/**
* 后置通知/返回通知 有异常不执行
*/
@AfterReturning (value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void afterReturning()
{
System.out.println ("AfterReturning--------");
}
/**
* 异常通知
*/
@AfterThrowing(value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void afterThrowing()
{
System.out.println ("AfterThrowing--------");
}
/**
* 环绕通知
*/
@Around (value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println ("环绕之前......");
//被增强的方法执行
proceedingJoinPoint.proceed ();
System.out.println ("环绕之后.......");
}
}
? 5.对公共切入点进行抽取
@Around (value = "pointdemo()")
public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println ("环绕之前......");
//被增强的方法执行
proceedingJoinPoint.proceed ();
System.out.println ("环绕之后.......");
}
//相同切入点抽取
@Pointcut(value = "execution(* com.Spring5_AOP_annotation.bean.User.add(..))")
public void pointdemo()
{
}
? 6.多个增强类对同一个方法进行增强,设置增强类优先级
? 1、在增强类上面添加注解@Order,数字类型值越小优先级越高
2、AspectJ配置文件方式(了解)
<?xml version="1.0" encoding="UTF-8"?>
4、数据库事务、JDBCTemplate
(1) 简介、测试
1.什么是JDBCTemplate
? Spring框架对JDBC进行封装,使用JDBCTemplate方便实现对数据库的操作
2.在springxml文件中配置数据库连接池,配置JDBCTemplate对象注入Datasource
properties 文件
driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?&useSSL=false&serverTimezone=UTC
userName=root
password=wh.0410
-
测试类
ApplicationContext context = new ClassPathXmlApplicationContext ("XML/Template/Te.xml"); BookService bookService = context.getBean ("bookService", BookService.class); bookService.addBook (new Book ("1","三体","已售"));
(2)JDBCTemplate操作数据库(增删查改)
package com.Spring_JdbcTemplate.Dao;
import com.Spring_JdbcTemplate.entity.Book;
public interface BookDao {
public void add(Book book);
public void update(Book book);
public void delete(String BookId);
}
package com.Spring_JdbcTemplate.Dao;
import com.Spring_JdbcTemplate.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class BookDaoimpl implements BookDao{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void add(Book book) {
String sql = "insert into t_book values (?,?,?)";
int update = jdbcTemplate.update (sql, book.getBookId (), book.getBookName (), book.getUstatus ());
System.out.println (update);
}
@Override
public void update(Book book) {
String sql = "update t_book set BookName = ?,ustatus = ? where BookId = ?";
int update = jdbcTemplate.update (sql, book.getBookName (), book.getUstatus (), book.getBookId ());
System.out.println (update);
}
@Override
public void delete(String BookId) {
String sql = "delete from t_book where BookId = ?";
jdbcTemplate.update (sql,BookId);
}
}
package com.Spring_JdbcTemplate.Service;
import com.Spring5_demo3.Dao.UserDao;
import com.Spring_JdbcTemplate.Dao.BookDao;
import com.Spring_JdbcTemplate.Dao.BookDaoimpl;
import com.Spring_JdbcTemplate.entity.Book;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookService {
//注入dao
@Autowired
private BookDao bookDao;
public void addBook(Book book)
{
bookDao.add(book);
}
public void updateBook(Book book)
{
bookDao.update(book);
}
public void DeleteBook(String BookId)
{
bookDao.delete(BookId);
}
}
? 1.JdbcTemplate查询返回某个值
/**
* 查询返回某个值
* @return
*/
@Override
public Integer selectCount() {
String sql = "select count(*) from t_book";
Integer count = jdbcTemplate.queryForObject (sql, Integer.class);
return count;
}
? 2.JdbcTemplate查询返回对象
/**
* 返回对象
* @param BookId
* @return
*/
@Override
public Book queryOnebook(String BookId) {
String sql = "select * from t_book where BookId = ?";
Book book = jdbcTemplate.queryForObject (sql, new BeanPropertyRowMapper (Book.class), BookId);
return book;
}
? 3.JdbcTemplate查询返回集合
/**
* 查询返回集合
* @return
*/
public List queryBookList()
{
String sql = "select * from t_book";
List books = jdbcTemplate.query (sql, new BeanPropertyRowMapper (Book.class));
return books;
}
4.JdbcTemplate批量操作(批量添加修改删除)
? 参数一:sql语句 参数二:List集合,添加多条记录
/**
* 批量添加
* @param batchArgs
*/
public void batchAdd(List
(3)事务操作
1.什么是事务?
? 事务是数据库操作的最基本单元,逻辑上一组操作,要莫都成功要么都失败。
2.事务的特性(ACID)
? 原子性
? 一致性
? 隔离性
? 持久性
3.事务环境
? 数据库事务环境
4.事务的操作
? 1-注意:事务一般添加到JavaEE三层结构的Service层上
? 2-在Spring进行事务管理操作
? 有两种方式 :编程式事务管理和声明式事务管理
? 开发中一般用声明式事务管理
? 3-声明式事务管理
? ①基于注解方式
? ②基于xml配置文件方式
? 4.在Spring进行声明式事务管理,底层使用AOP
? 5.在Spring事务管理API
? (1) 提供了一个接口,代表事务管理器。这个接口针对不同的框架提供了不同的实现类
? 0-修改xml文件
<?xml version="1.0" encoding="UTF-8"?>
? (2)-创建事务管理器
? (3)-开始事务注解
? (4)-在service类上面(或者service类里面的方法上面添加事务注解)
? ①@Transactional,这个注解添加到类的上面,也可以添加方法上面
? ②如果把这个注解添加类的上面,这个类里面的所有方法都添加事务
? ③如果把这个注解添加方法上面,位这个方法 添加事务
? (5)事务注解中的参数
? 1-propagation :事务传播行为
? 多事务方法直接进行调用,这个过程中事务时如何进行管理的
? 事务方法:对数据库表数据进行变化的操作
?
? 2-Ioslation:事务隔离级别
? ·1 事务有特性称为隔离性,多事务操作之间不会产生影响,不考虑隔离将会 产生很多问题
? ·2 有三个读的问题 脏读、不可重复读、虚(幻)读

脏读
? 不可重复读
虚读:一个未提及的事务读取到了已提交事务中添加的数据
通过事务的隔离级别可以解决上述问题:
?
? Mysql默认隔离级别为REPEATABLE READ
? 3-timeout:超过时间
? 事务需要在一定的时间内进行提交,如果不提交就进行回滚
? 默认值是- 1,设置时间以秒为单位进行计算
? 4-readOnly:是否只读
? 默认值为false,表示可以查询,可以进行添加修改删除操作
? 如果设为true就只能查询
? 5-rollbackFor:回滚
5.XML声明式事务管理
1.在spring配置文件中进行配置
? ①配置事务管理器
? ②配置通知
? ③配置切入点和切面
2.完全注解声明式
? ①创建配置类,使用配置类代替xml配置文件
package com.Spring_JdbcTemplate.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.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration //配置类
@ComponentScan(basePackages = "com.Spring_JdbcTemplate") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource()
{
DruidDataSource dataSource = new DruidDataSource ();
dataSource.setDriverClassName ("com.mysql.cj.jdbc.Driver");
dataSource.setUrl ("jdbc:mysql://localhost:3306/test?&useSSL=false&serverTimezone=UTC");
dataSource.setUsername ("root");
dataSource.setPassword ("wh.0410");
return dataSource;
}
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource)
{
JdbcTemplate jdbcTemplate = new JdbcTemplate ();
//到IOC容器中根据类型找到dataSource 并注入dataSource
jdbcTemplate.setDataSource (dataSource);
return jdbcTemplate;
}
//创建事务管理器duix
@Bean
public DataSourceTransactionManager getdataSourceTransactionManager(DataSource dataSource)
{
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager ();
//到IOC容器中根据类型找到dataSource 并注入dataSource
dataSourceTransactionManager.setDataSource (dataSource);
return dataSourceTransactionManager;
}
}
? ②创建测试方法
@Test
public void accountMoneyAnno()
{
ApplicationContext context = new AnnotationConfigApplicationContext (TxConfig.class);
UserService userService = context.getBean ("userService", UserService.class);
userService.accountMoney ();
}
5、Spring5框架的新功能
1.增加功能
除
2.核心特性
? (1)@Nuallable注解可以使用在方法、属性、参数上面,表示方法返回可以为空,属性值可以为空
? 参数值可以为空
? (2)Spring5核心容器支持函数式风格GenericApplicationContext 创建对象
@Test
public void GenericApplicationContextTest()
{
//创建GenericApplicationContext对象
GenericApplicationContext genericApplicationContext = new GenericApplicationContext ();
//调用context方法对象注册
genericApplicationContext.refresh ();
genericApplicationContext.registerBean (Stu.class,()->new Stu ());
//获取在Spring注册的对象
Stu stu = (Stu) genericApplicationContext.getBean ("com.Spring_JdbcTemplate.Test.Stu");
System.out.println (stu);
}
(3)Spring5支持整合JUnit5
? 1-整合JUnit4
@RunWith (SpringJUnit4ClassRunner.class) //指定单元测试框架
@ContextConfiguration("classpath:XML/Template/Te2.xml") //加载配置文件
public class JTest4 {
@Autowired
private UserService userService;
@Test
public void test1()
{
userService.accountMoney ();
}
}
? 2-整合JUnit5
@ExtendWith (SpringExtension.class)
@ContextConfiguration("classpath:XML/Template/Te2.xml")
public class JTest4 {
@Autowired
private UserService userService;
@Test
public void test1()
{
userService.accountMoney ();
}
? 3-使用复合注解整合上述俩个注解
@SpringJUnitConfig(locations = "classpath:bean1.xml")
public class JTest5 {
@Autowired
private UserService userService;
@Test
public void test1() {
userService.accountMoney();
} }
3.WebFlux
(1)简单介绍
? ①SpringWebFlux式Spring5新加的模块,用于web开发,与SpringMVC功能类似,WebFlux使用
当前一种比较流行的响应式编程出现的框架
? ②使用传统web框架,比如SpringMVC,这些基于Servlet容器,WebFlux是一种一部非阻塞的框架,异步非阻塞的框架再Servlet3.1以后才支持,核心是基于reactor的相关API实现
? ③异步非阻塞:
? 异步、同步:调用者发送请求,如果要等着对方回应后才能做其他事情则称为同步,若发送请求后可以不等待回应就去做其他事情称为异步(Ajax就是异步请求,局部改变动态页面)
? 阻塞、非阻塞:被调用者收到请求后,在做完请求任务后才给出反馈就是阻塞,若收到请求后马上就做出反馈就是非阻塞
? ④WebFlux的特点:
? 1-非阻塞式:可以在有限的资源下,提高系统的吞吐量和伸缩性(即在有限的 资源下处理更多的请求)
? 2-函数式编程:Spring框架基于java8,WebFlux使用java8函数时编程方式实现路由请求
?
(2)响应式编程
? 何为响应式编程是一种面向数据流和变化传播的编程范式,这意味着可以在编程语言中很方便的表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播
(3)WebFlux 执行流程和核心API
(4)SpringWebflux(基于注解编程模型)
(5)SpringWebflux(基于函数式编程模型)
先看看springmvc boot 后再回头看5的新特性
尚硅谷Spring5框架教程(idea版)_哔哩哔哩_bilibili