Spring5

Spring5

1、Spring 概念

Spring是轻量级的开源的JavaEE框架,用于解决企业应用开发的复杂性
两个核心(1)控制反转,把创建对象过程交给Spring进行管理
(2) AOP,面向切面,在不修改源代码的情况下进行功能增强
特点:(1)方便解耦,简化开发
(2)AOP编程支持
(3) 方便程序测试
(4)方便和其他框架进行整合
(5)方便进行事务操作
(6)降低JavaEE API的使用难度
(7)源码是经典学习规范

案例1

导入基本jar包

<?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.dragonk.spring5.User"></bean></beans>

@Test
public void testAdd(){    
ApplicationContext context = new 
ClassPathXmlApplicationContext("bean1.xml");   
User user = context.getBean("user", User.class);    System.out.println(user);   
user.add();}

2、IOC容器

(1)IOC底层原理
主要使用技术,xml解析,工厂模式,反射
第一步,xml配置文件


//第二步
class UserFactory{
public static UserDao getDao(){
   //通过xml解析获得class路径
   String classValue =.....
   //通过反射获得class对象
   Class clazz = Class.forName(classValue);
   return (UserDao)clazz.newInstance();
}
}

(2)IOC接口(BeanFactory, ApplictationContext)
两个接口
(a)BeanFactory,Spring内置接口,IOC基本实现,Spring内部接口
加载配置文件不会创建对象,使用时创建
(b) ApplictationContext,BeanFactory子接口,提供更强大的功能,供开发人员使用,加载配置文件会创建对象
ApplictationContext接口实现类
1、FileSystemXmlApplicationContext
2、ClassPathXmlApplicationContext
(3) IOC操作Bean管理(基于xml)
(4)IOC操作Bean管理(基于注解)

IOC操作Bean管理

(两个操作 1、创建对象 2、注入属性)

基于XML基础

1.1、基于xml方式创建对象
(1)spring 配置文件中,使用bean标签,标签里面添加对应属性,可以实现对象创建
(2)在bean标签有很多属性
id属性,唯一标识;class属性,类全路径(包类路径)
(3)创建对象时候,默认也是执行无参构造方法完成对象的窗口
1.2、基于xml方式注入属性(DI:依赖注入)
(1) 常规,set注入,创建无参构造的对象,调用set方法注入属性;
xml bean标签中,使用property属性,name,类里面的属性,value,向属性注入的值
<bean id="",class = ""> <property name="" value=""><property> </bean>
(2) 常规,构造方法注入,使用有参构造的对象。name,构造方法形参名,value,注入的值
<bean id="",class = ""> <constructor-arg name="" value=""></constructor-arg> <constructor-arg name="" value=""></constructor-arg> </bean>
1.3 p名称空间注入
<beans xmlns="http://www.springframework.org/schema/beans"      
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
--- xmlns:p="http://www.springframework.org/schema/p"----      
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
set 注入 ,name,类属性,value,注入的值
<bean id="",class = "" p:name1 = "value" p:name2 = "value2"> </bean>
1.4 xml注入其他类型
(1) 注入空值
<bean id="",class = ""> <property name="" ><null/> <property> </bean>
(2)属性值包含特殊符号
对特殊符号进行转义 > > < <
把带特殊符号内容写入到CDATA ,如下 <<南京>>
<bean id="",class = ""> <property name="" > <value><![CDATA[ <<南京>> ]]></value> <property> </bean>
(3)外部bean

创建bean对象     
<bean id="userDao",class = ""> </bean>
          <bean id="userService",class = ""> 
          name 类里面属性名称  ref bean标签对象 id 值
           <property name ="" ref ="userDao">
          </bean>
      (4)内部bean和级联赋值
          一对多关系:部门和员工,实体类表示一对多关系
         内部bean  
<bean id="emp",class = ""> 
          <property name="" value=""><property>
           <property name="" value=""><property>
         <bean id="dept",class = "">
          <property name="" value=""><property>
          </bean>    
         </bean>
  级联赋值
<bean id="dept",class = "">
          <property name="id" value=""><property>
          </bean>     
          <bean id="emp",class = ""> 
          <property name="" value=""><property>
           <property name="" value=""><property>
            <property name ="" ref ="dept">
            //需要get方法
            <property name ="dept.id" values ="">
         </bean>
        (5)注入集合属性
        注入数组类型
    <bean id="stu",class = "">
             <property name="course">
             <array>
             <value></value>
             <value></value>
             <value></value>
             </array>
             <property>
 </bean>    
   注入List集合类型
 <bean id="stu",class = "">
             <property name="list">
             <list>
             <value></value>
             <value></value>
             <value></value>
             </list>
             <property>
          </bean>  
        注入Map集合类型
  <bean id="stu",class = "">
             <property name="maps">
             <map>
                <entry key="" value="">
                <entry key="" value="">
                <entry key="" value="">
             </map>
             <property>
          </bean>  
         注入Set集合类型
<bean id="stu",class = "">
             <property name="maps">
             <set>
               <value></value>
               <value></value>
               <value></value>
             </set>
             <property>
          </bean>  
        集合中设置对象类型   
 <bean id="demo1",class = "">
          <property name="id" value=""><property>
          </bean>     
           <bean id="demo2",class = "">
          <property name="id" value=""><property>
          </bean>     
        <bean id="stu",class = "">
             <property name="maps">
             <list>
              <ref bean ="demo1"></ref>
              <ref bean ="demo2"></ref>
              <ref bean =""></ref>
             </set>
             <property>
          </list>  
  集合注入部分提前出来
          spring配置文件引入空间util
           <beans xmlns="http://www.springframework.org/schema/beans"       
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<--- xmlns:util="http://www.springframework.org/schema/util"----       
 xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd"
                           <--- http://www.springframework.org/schema/utils  http://www.springframework.org/schema/util/spring-utils.xsd --->
           使用util标签完成list集合类型注入
  <util : list id ="book">
          <value></value>
          <ref bean =""></ref>
          </util:list>
         <bean id="demo3",class = "">
            <property name="list" ref = "book"> </property>
         </bean>

FactoryBean

Spring有两种类型 bean,一种普通bean,另一种工厂bean(FactoryBean)
普通bean在配置文件中定义bean类型就是返回类型
工厂bean在配置文件中定义bean类型可以和返回类型不一样
第一步 创建类,实现FactoryBean
//Object getObject() Class<?> getObjectType(); boolean isSingleton();
第二步 实现接口里的方法,实现的方法中定义返回的bean类型

Bean作用域

1、Spring里面,设置创建bean是单实例还是多实例,默认单实例
设置bean 标签属性scope,默认值singleton 单实例,加载配置文件的时候会创建对象,prototype 多实例,调用getBean()创建不同的对象
request 创建对象放到request域,session 创建对象放到session域

Bean生命周期

(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)把bean实例传递bean后置处理器方法 (需要添加后置处理器)创建类 实现BeanPostProcessor接口 重写 postProcessBeforeInitialization(Object bean,String beanName)
,后置处理器类需要在配置文件中配置,,会对当前配置文件bean实例全部添加后置处理器
(4)调用bean的初始化方法(需要进行配置) bean标签属性 init-method="方法名"
(5)把bean实例传递bean后置处理器方法 (需要添加后置处理器) 创建类 实现BeanPostProcessor接口 重写 postProcessAfterInitialization(Object bean,String beanName)
(6)bean可以使用
(7)容器关闭时候,调用bean的销毁方法(需要进行配置销毁的方法) destory-method="方法名" 或者 手动销毁 (ClassPathXmlApplicationContext) context.close();

xml自动装配

手动装配,通过property,ref在配置文件中配置
<bean id="userDao",class = ""></bean>
<bean id="userService",class = ""> 
        <property name ="" ref ="userDao">
</bean>
自动装配,根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入,bean标签属性autowire
byName 根据属性名称进行注入 注入值bean的id值和类属性名称一样
<bean id="userDao",class = ""></bean>
<bean id="userService",class = "" autowire ="byName"> //userService对应中有一个变量名称为userDao的userDao所有指代的对象 
</bean>
byType 根据属性类型进行注入 ,根据类型找到对应类型指代,如果有多个相同的bean类型对象,无法使用。

外部属性文件

xml 从property文件中读取 数据库信息
(1)直接配置
配置德鲁伊连接池 ,引入连接池jar包,

<bean id="" class="德鲁伊jar包所在路径">
      <property name = "driverClassName" value ="com.mysql.jdbc.Driver">
      <property name = "url" value ="jdbc:mysql://localhost:3306/test">
      <property name = "username" value ="root">
      <property name = "password" value ="root">
</bean>

(2)外部配置

创建配置文件 jdbc.properties,添加键 == 值对
    把外部properyties属性文件引入spring配置文件,引入context名称空间
      <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 --->
   
   在spring配置文件使用标签引入外部配置文件
   <context:property-placeholder location="classpath:jdbc.properties">
    
 <bean id="" class="德鲁伊jar包所在路径">
         <property name = "driverClassName" value ="${key}">
         <property name = "url" value ="${key}">
         <property name = "username" value ="${key}">
         <property name = "password" value ="${key}">
   </bean>
   

基于注解

1、注解是代码特殊标记,格式@注解名称(属性名称=属性值,属性名称=属性值...)
注解可以作用在类,方法,属性等
使用注解目的,简化xml配置,配置使用更优雅

2、Spring针对Bean管理中创建对象提供注解
(1)@Component
(2) @Service
(3) @Controller
(4) @Repository
上面的四个注解,功能是一样的,都可以创建Bean的实例,一般习惯把每个注解用在各个层中

 第一步,引入依赖spring-aop依赖
 第二步,  开启组件扫描
    <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:component-scan base-package="被扫描的包路径"></context:component-scan>

第三步,创建类,在对象类上加对象注解
@Component(value="demo") ==>
public class ......
//注解里面value可以不写,默认是类名称,首字母小写

开启组件扫描中的细节配置
1、自行配置扫描策略

<context:component-scan base-package="com.atguigu.springmvc" use-default-filters="false">
   <context:include-filter type="annotation"
          expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
//user-defalut-filters ="false" 不使用默认配置扫描,自行配置规则
//context:include-filter 设置扫描那些内容,type="annotation" expression="org.springframework.stereotype.Controller" 只扫描注解为@Controller的类

2、默认扫描策略,不去扫描那些内容 context:exclude-filter 设置不扫描什么

<context:component-scan base-package="com.atguigu.springmvc">
	<context:exclude-filter type="annotation"
        	expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

基于注解方法实现属性注入

(1)@AutoWired 根据属性类型自动注入 --> byType
(2) @Qualifier("") 根据属性名称进行注入 -->byName
要与@AutoWired一起使用,相同类 型,多个实现类使用
(3) @Resource 可以进行类型,也可以根据名称注入,由javax拓展包提供
@Resource 根据类型进行注入 @Resource("") 根据名称进行注入
(4) @Value 注入普通类型

完全注解开发

创建配置类替代xml配置文件
@configuration 注解标记类,为配置类
包扫描 @CompentScan(basePackage={""}) 标记配置类
加载配置类 ApplicationContext c = new AnnotationConfigApplicationContext(SpringConfig.class);

3、AOP

面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑间各部分耦合度减低,提高可重用性,提高开发效率。
不修改原有代码的功能,方便添加新功能。

底层原理 动态代理

1、JDK动态代理,使用接口进行增强
使用Proxy类创建代理对象,调用newProxyInstance方法,方法有三个参数,参数一,类加载器,参数二,增强方法所在的类,这个类实现的接口,支持多个接口
参数三,实现这个接口InvocationHandler ,实现(invoke(Object,Method,Object[])方法,)创建代理对象,写增强的方法,原方法 method.invoke(obj,args)
2、CGLIB动态代理,使用子父类进行增强

AOP术语

1、连接点,类里面那些方法可以被增强,这些方法称为连接点。
2、切入点,实际被真正增强的方法,称为切入点。
3、通知(增强),实际增强的逻辑部分称为通知(增强),通知有多种类型
前置通知:被增强方法之前的逻辑
后置通知:被增强方法之后的逻辑
环绕通知:被增强方法前后的逻辑
异常通知:被增强方法出现异常执行的逻辑
最终通知:被增强方法无论有无异常,永远会被执行
4、切面
动作,把通知应用到切入点的过程

AOP操作

1、spring框一般基于AspectJ实现AOP操作
AspectJ不是Spring组成部分,独立AOP框架,一般把它和Spring一起使用,完成AOP操作
2、基于AspectJ实现AOP操作
(1)基于xml配置文件
(2) 基于注解方式实现(常用)
3、准备工作
(1) 引入依赖 spring- aspects,springsource.net.sf.cglib,springsource.org.aopaliance,springsource.org.aspectj.weaver
(2)切入点表达式
知道对哪个类里面的哪个方法进行增强
execution([权限修饰符][返回值类型][类的全路径][方法名]([参数列表]))
例1 execution(* com.dragonk.dao.demoDao.add(..)) 对demoDao类里的add进行增强
例2 execution(* com.dragonk.dao.demoDao.* (..)) 对demoDao类里的所有方法进行增强
例3 execution(* com.dragonk.dao.. (..)) 对dao包所有类里的所有方法进行增强

AspectJ注解

(1)注解扫描
(2)使用注解创建User和UserProxy对象
(3)增强类上面添加注解@Aspect
(4)开启生成代理对象
注解:
@configuration 注解标记类,为配置类
包扫描 @CompentScan(basePackage={""}) 标记配置类
@EnableAspectJAutoProxy(proxyTargetClass = "true")
(5)配置不同类型的通知,增强类方法上添加通知类型注解,使用切入点表达式
前置通知@Before(execution(* com.dragonk.User.add(..))) 方法之前执行
后置通知@AfterReturning (execution(* com.dragonk.User.add(..))) ... 方法返回值之后执行
最终通知@After 方法执行后一定会被执行
异常通知@AfterThrowing(execution(* com.dragonk.User.add(..))) 方法抛出异常后执行
环绕通知@Around(execution(* com.dragonk.User.add(..))) 对方法执行前后进行修饰, 形参(ProceedingJonPoint p), p.process();执行的被增强方法
(6)公共切入点进行抽取
@PointCut(execution(* com.dragonk.User.add(..))
public void point(){
}
其他通知直接使用公共切点 通知里直接写被PointCut修饰的类名
@Before("point()")
@After("point()")
(7)有多个增强类对同一个类方法进行增强,设置优先级
在增强类上添加注解@Order(数字值),数字类型值越小,优先级越高
#### AspectJ配置文件
(1)spring配置文件创建两个bean对象
(2)在spring配置文件中配置切入点
配置文件:名称空间aop aop:aspectj-autoproxy</aop:aspectj-autoproxy>

<aop:config>
      <!-- 切入点-->
      <aop:pointcut id ="p" ,expression="execution(* com.dragonk.User.add(..)">
      <!-- 配置切面-->
      <aop:aspect ref ="UserPorxy">
          <aop:befor method="before" pointcut-ref="p">
       </aop:aspect>
   </aop:config>

4、JdbcTemplate

spring框架对JDBC进行看封装,使用JdbcTemplate可以方便的对数据库实现增查删改
1、准备工作

 (1)引入依赖 spring-jdbc mysql-conntect spring-tx  事务 spring-orm整合其他框架
     (2)spring配置文件配置数据库连接池
     (3)创建jdbcTemplate对象
     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     <!-- 注入DataSource-->
     <property name="dataSource" ref="dataSource"></property>
     </bean>
 (4)创建service类,创建dao,注入jdbcTemplate对象

JdbcTemplate操作数据库

(1)创建数据库对应实体类
(2)编写service,dao层
dao层JdbcTemplate中的方法
update(sql,value...) 增,更
delete(sql,value... 删
query(sql,RowMapper,value...) 查返回对象集合
queryForObject(sql,RowMapper,value..) 查返回对象
批量操作
batchUpdate(sql,list) 批量添加和修改,删除

5、事务管理

事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败,如果有一个失败所有操作都失败。
原子性,一致性,隔离性,持久性
第一步,开启事务
第二步,进行业务操作
第三步,无异常提交事务
第四步,如果出现异常,事务回滚
Spring进行事务管理操作,编程式事务管理和声明式事务管理(使用)
事务添加到JavaEE三层结构Service层

声明式事务管理

1、基于xml方式
2、基于注解方法(使用)
底层使用AOP原理

Spring事务管理API

(1)提供一个接口,代表事务管理器,这个接口针对不同框架提供不同的实现类
接口 PlatformTransactionManager
实现类DataSourceTransactionManager jdbc,,mybatis
实现类HhibernateTransactionManager hibernate

注解方式实现声明式

1、spring配置文件中创建事务管理器
       
2、spring配置文件中开启事务注解
引入名称空间tx <tx:annotation-driven
transaction-manager="transactionManager"></tx:annotation-driven>
3、service类上面或里面的方法加上事务的注解@Transactional
注解在类上,这个类里面所有的方法都添加事务,注解在方法上,给方法添加事务

声明式参数配置

1、propagation,事务传播行为
REQUIRED 如果有事务运行,当前方法在这个事务运行,否则就启动一个新的事务,并在自己的事务内运行
如果当前方法有事务,调用无事务的方法,那无事务的方法使用有事务的方法,如果当前方法没有事务,调用有事务的方法之后,创建新的事务。
REQUIRED_NEW 当前事务必须启动新事务,并在它自己的事务内运行,如果有事务运行,应该讲它挂起
当前方法调用别的方法一定会创建新的事务
SUPPORTS 如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
NOT_SUPPORT 当前的方法不应该运行在事务中,如果有运行的事务,将它挂起
MANDATORY 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常。
NEVER 当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新事务并在它自动的事务内运行
2、isslation,事务隔离级别
解决并发读问题,脏读(多个事务之间,一个未提交的事务读取到了另一个未提交事务的数据),不可重复读(一个未提交的事务读取到了另一个提交事务修改的数据),幻读(一个未提交的事务读取到另一个提交事务添加的数据)
隔离级别,读未提交,读已提交,可重复读,串行化,mysql默认可重复读
3、timeout,超时时间
事务在规定时间内需要提交,超时的事务会回滚,默认值-1,设置时间以秒为单位
4、readOnly,是否只读,默认值false,可以查询,可以添加修改删除操作,true,只能查询
5、rollbackFor,回滚
设置出现哪些异常进行事务回滚
6、noRollbackFor,不回滚
设置出现哪些异常不进行事务回滚

xml方式

1、配置事务管理器
2、配置通知
tx:advice
tx:attributes
3、配置切入点和切面
aop:config,aop:pointcut

完全注解开发

1、创建配置类替代xml
@Configuration
@ComponentScan
@EnableTransactionManagement 开启事务
创建数据库连接池对象

@Bean 
   public DuridDataSource getDuridDataSource(){
    DuridDataSource dataSource = new  DuridDataSource();
    dataSource .setXxx();
    dataSource .setXxx();
    dataSource .setXxx();
    return dataSource;
   }

创建JdbcTemplate对象

@Bean
   public JdbcTemplate  getJdbcTemplate(DataSource dataSource){//根据类型在容器中查找对象
    JdbcTemplate jdbcTemplate = new JdbcTemplate();
    jdbcTemplate.setDataSource(dataSource);
    return  jdbcTemplate ;
   }

创建事务管理器对象
.....

6、Spring5新特性

1、整个Spring5基于JDK8,兼容JDK9,许多不建议使用的类和方法进行了删除
2、Spring5.0框架自带了通用的日志封装
(1)Spring5移除了Log4jConfigListener,官方建议使用Log4j2
(2) Spring5整合Log4j2
(3)导入依赖,lo4j-api-2,log4j-core-2,log4j-slf4-impl-2,slf4-api-1
(4)创建log4j2.xml,名称固定,内容固定,手动输出 Logger log = LoggerFactory.getLogger(UserLog.class);
3、支持@Nullable注解,可以使用方法,属性,参数,表示方法返回值,属性,参数值可以为空
4、支持函数式编程GenericApplicationContext
GenericApplicationContext context = new GenericApplicationContext();
向context注册User对象
context.refresh();
context.registerBean(User.class,()->new User());
获取spring注册对象
context.getBean("全类名")
5、Spring5支持整合JUnit5
(1)整合JUnit4
引入测试依赖spring-test,引入JUnit4
@RunWith(SpringJUnit4ClassRunner.class)//单元测试框架@ContextConfiguration("classpath:bean1.xml")//加载配置文件public class JTest4 {    @Autowired    private TestService testService;    @Test    public void test1(){        testService.sumAllUser();    }}
(2)整个JUnit5
引入测试依赖spring-test,引入JUnit5
@ExtendWith(SpringExtension.class)@ContextConfiguration("classpath:bean1.xml"
)public class JTest5 {  @Autowired  private TestService testService; 
@Test  public void test(){    testService.sumAllUser();  }}

复合注解@SpringJUnitConfig(location="classpath:bean1.xml")替代上面两个注解
6、SpringWebFlux
Spring5添加的新的模块,用于web开发,功能与SpringMVC类似,Webflux使用当前一种比较流行响应式编程出现的框架
传统的web基于Servlet容器,如SpringMVC,Webflux是一种异步非阻塞的框架,Servlet3.1以后才支持,核心基于Reactor相关API实现的
异步同步,非阻塞和组塞
针对的对象不同,同步和异步是针对调用者,调用者发送请求,等对象回应再做其他操作,同步,否则异步;
非阻塞和组塞是针对被调用者,调用者受到请求,做完请求给反馈是阻塞,直接给反馈再做任务是非阻塞;
特点:非阻塞式,有限资源下,提高系统吞吐量和伸缩性,以Reactor为基础;函数式编程实现路由请求;
与SpringMVC比较,都可以使用注解方式,运行在Tomcat容器中,SpringMVC采用命令式编程,SpringWebFlux采用异步响应式编程
使用场景:微服务的网关
1、响应式编程(Reactor实现)
定义:是一种面向数据流和变化传播的编程范式,相关的计算模型可以自动将变化的值通过数据流进行传播
设计模式,观察者模式:JDK8,Oberver和Observable,JDK9 Flow
响应式编程操作需要满足Reactive规范,Reactor核心类,Mono和Flux,这两个类实现接口Publisher,提供丰富操作符。
Flux对象实现发布者,返回N个元素;Mono实现发布者,返回0或者1个元素。
Flux和Mono都是数据流的发布者,使用Flux和Mono可以发出三种数据信号。
元素值,错误信号,完成信号,错误信号和完成信号都代表终止信息,终止信号和完成信号都代表终止,终止信号告诉订阅者数据量结束,错误信号终止数据流同 时把错误信息传递给订阅者。
发送数据流,Flux.just或者Mono.just,Flux.fromArray(),Flux.fromIterable(),Flux.fromStream()
完成信号和错误信号不能共存,没有发送任何元素值,而是直接发送错误或完成信号,表示空数据流
如果没有完成和错误信号,表示无限流。
发送错误,Flux.error()

订阅者订阅发布,才能操作发布者中的数据流
数据流.subscribe(System.out::println)

操作符,
map映射为新元素,元素操作
flatMap映射为流,把元素转换为流,再合并成一个流
2、SpringWebflux执行流程和核心API
基于Reactor,默认使用容器Netty,Netty是高性能的NIO框架,异步非阻塞的框架
(1)Netty,BIO阻塞,NIO非阻塞
  (2)核心控制器DispatchHandler,实现接口WebHandler,Mono<Void> handle(ServerWebExchange exchange);
     HandlerMapping 请求查询到处理的方法
     HandlerAdapter 真正负责请求处理
     HandlerResultHandler:响应结果处理
     ResourceWebHandler 静态控制器,处理静态资源
     WebHandlerDecorator 装饰控制器,附加功能
     RouterFucationWebHandler 路由控制器
(3)实现了两个函数式接口,RouterFunction(路由处理)和HandlerFuction(处理函数)
3、基于注解编程模型
第一步,创建Springboot工程,引入WebFlux依赖
SpringMVC方式实现,同步阻塞,基于SpringMVC+Servlet+Tomcat
SpirngWebflux方式实现,异步非阻塞方式,基于SpringWebflux+Reactor+Netty
4、基于函数式编程模式
(1)使用函数式编程模式操作,需要自己初始化服务器

(2)核心任务实现两个核心接口并启动需要的服务器,RouterFunction(实现路由功能,请求转发给对应的handler)和HandlerFunction(处理请求生成响应的函数)
(3)SpringWenFlux请求和响应不再是ServletRequest和ServletReponse,而是ServerRequest和ServerReponse
(4)初始化服务器,编写Router
(5) 创建服务器完成适配
(6) 最终调用
浏览器调用,WebClient调用

总结

 1、Spring概述
  (1)轻量开源JAVAEE框架,为了解决企业复杂性,核心组成IOC和AOP
 2、IOC容器
   (1)IOC底层原理
   (2)IOC接口
   (3)IOC操作Bean(xml)
   (4)IOC操作Bean(注解)
 3、AOP
     (1)AOP底层原理,动态代理JDK,CGLIB
     (2)术语,连接点,通知,切面,切入点
   (3)基于AspectJ实现AOP
  4、JdbcTemplate
    (1)crud和批量操作
  5、事务管理
    (1)事务概念
  (2)注解实现声明式事务管理
   6、Spring5新功能
    (1)整合日志
    (2)函数式注册对象
    (3)整合JUnit5
      (4) SpringWebflux使用
posted @ 2021-01-13 13:14  DragonK  阅读(131)  评论(0)    收藏  举报