spring5的回顾学习、记录和总结

此篇文章仅记录自己回顾学习笔记,有些许代码不齐,文章可方便学习过的同学快速浏览找到spring5涵盖的基本知识点,如有不足和错误,请大家多多指导

Spring概念

	Spring框架概述
	1. Spring是轻量级的开源的JavaEE框架
	2. Spring可以解决企业应用开发的复杂性
	3. Spring有两个核心部分:IOC和AOP
		(1)IOC:控制反转,把创建对象过程交给Spring进行管理
		(2)AOP:面向切面编程,不修改源代码进行代码增强
	4.Spring特点
		(1)方便解耦合,简化开发
		(2)AOP编程的支持
		(3)方便程序的测试
		(4)方便和其他框架进行整合
		(5)方便进行事务操作
		(6)降低API的开发难度
	5.选取Spring版本5.x进行学习总结

IOC容器

IOC底层原理

	IOC(概念和原理)
	1、什么是IOC
	 (1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
	 (2)使用IOC的目的:为了耦合度降低
	2、IOC底层原理
	 (1)xml解析、工厂模式、反射
	3、画图讲解IOC解析原理

IOC接口(BeanFactory)

	1、IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
	2、Spring提供IOC容器实现的两种方式:(两个接口)
	 (1)BeanFactory:IOC容器基本实现,是spring内部的使用接口,一般不提供开发人员进行使用
	 * 加载配置文件的时候不会创建对象,在获取对象(使用)才去创建对象。
	 (2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
	 *加载配置文件的时候就会把在配置文件的对象进行创建。(一般把耗时耗资源的在启动之前启动)
	3、ApplicationContext接口有两个主要实现类
		FileSystemXmlApplicationContext:填写系统磁盘下的xml路径
		ClassPathXmlApplicationContext:填写src下的xml路径

IOC操作Bean管理

	1、什么是Bean管理
	 (1)Bean管理指的是两个操作
	 (2)Spring创建对象
	 (3)Spring注入属性
	2、Bean管理操作有两种方式
	 (1)基于xml配置文件方式创建
	 (2)基于注解方式实现

IOC操作Bean管理(基于xml方式)

	1、基于xml方式创建对象
	 (1)在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
	 (2)在bean标签有很多属性,介绍常用属性
	 *id属性:唯一属性
	 *class属性:类全路径(包类路径)
	 (3)创建对象的时候,默认也是执行无参数构造方法完成的对象创建
	2、基于xml方式注入属性
	 (1)DI:依赖注入,就是注入属性
	 第一种注入方式:set方法注入(在Spring配置文件中使用bean创建对象并注入property)
	<bean id="book" class="包路径">
	 	<property name="bname" value="zhangsan"></property>
	</bean>
	 第二种注入方式:有参构造注入(constructor-arg)
	 <bean id="book" class="包路径">
		<constructor-arg name="bname" value="zhangsan"></constructor-arg>
		<constructor-arg index="1" value="zhangsan"></constructor-arg>
	</bean>
	 (2)p名称空间注入
	  使用p名称空间注入,可以简化基于xml配置的方式
	  第一步 添加p名称空间在配置文件中
 xmls:p=“http://www.springframework.org/schema/p”
	  第二步 加入属性
 <bean id="book" class="包路径" p:name="" p:author=""></bean>
	 3、xml注入其他类型属性
	  (1)字面量
	   *设置null值
   	<property name="bname">
  	     <null/>
   	</property>
	   	*包含特殊符号(<<南京>>)。  1、可以转义,&gt;    2、特殊写到CDATA 
	<property name="bname">
   	     <value><![CDATA[<<南京>>]]></value>
   	</property>
	 4、注入属性---外部bean
	  (1)创建两个类service类和dao类
	  (2)在service里调用dao类
	  (3)在Spring配置文件中配置(name:类中名称,ref其他外部beanid)
   	<bean id="userService" class="包路径">
    		<property name="userDao" ref="userDao"></property>
    </bean>
    <bean id=“userDao” class=“包路径”></bean>
	 5、注入属性-内部bean
	  (1)一对多关系:部门和员工(一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多)
	  (2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性表示。
	  		在员工类中有一个属性是部门对象
	  (3)在Spring配置文件中的配置
	<bean id="emp" class="">
		<property name="ename" value="lucy"></property>
		<property name="egender" value=""></property>
		<property name="dept">
	     <bean id="dept" class="">
	     		<property name="dname" value="安保部"></property>
	     </bean>
		</property>
   </bean>
      6、注入属性-级联赋值(自己理解,类似外部bean)
       (1)第一种写法
	<bean id="emp" class="">
		<property name="ename" value="lucy"></property>
		<property name="egender" value=""></property>
		<property name="dept" ref=“dept”></property>
   </bean>
   <bean id="dept" class="">
   		<property name="dname" value="安保部"></property>
   </bean>
	   (2)第二种写法(此写法需要在emp对象内设置get方法)
 	<bean id="emp" class="">
 			<property name="ename" value="lucy"></property>
			<property name="egender" value=""></property>
			<property name="dept" ref=“dept”></property>
			<property name="dept.dname" value=“财务部”></property>
   </bean>
   <bean id="dept" class="">
   			<property name="dname" value="安保部"></property>
   </bean>
	  7、xml注入集合类型
	   (1)注入数组集合属性
	   (2)注入List集合属性
	   (3)注入Map集合属性
	   第一步 创建类并创建这几种属性
	   第二部 在Spring配置文件中书写
	<bean id="" class="">
   			<property name="数组名称">
   					<array>
   							<value>内容1</value>
   							<value>内容2</value>
   					</array>
   			</property>
   </bean>
     <bean id="" class="">
   			<property name="list名称">
   					<list>
   							<value>内容1</value>
   							<value>内容2</value>
   					</list>
   			</property>
   </bean>
     <bean id="" class="">
   			<property name="map名称">
   					<map>
   							<entry key="" value=""></entry>
   							<entry key="" value=""></entry>
   					</map>
   			</property>
   </bean>
     <bean id="" class="">
   			<property name="set名称">
   					<set>
   							<value>内容1</value>
   							<value>内容2</value>
   					</set>
   			</property>
   </bean>
	 8、在集合里面设置对象类型的值(Spring中配置文件写法)
	<bean id="" class="">
		<property name="coustLIst">
					<list>
						<ref bean="course1"></ref>
						<ref bean="course2"></ref>
					</list>
			</property>
	</bean>
	<bean id="course1" class=“”>
		<property name="cname" value="Spring"></property>
	</bean>
	<bean id="course2" class=“”>
		<property name="cname" value="Mybatis"></property>
	</bean>
	 9、把集合类提取出来作为公共。    (将公共部分相当于外部bean注入)
	 (1)现引入新的命名空间叫做util,可引用其他的复制进行修改
	 <util:list id="bookList">
	 		<value>西游记</value>
	 		<value>红楼梦</value>
	 		<value>水浒传</value>
	 </util:list>
	 <bean id="book" class="">
	 		<property name="list" ref="bookList"></property>
	 </bean>

IOC操作Bean管理(FactoryBean)

	1、Spring中有两种类型Bean,一种是普通bean,另外一种是工厂bean(FactoryBean)
	2、普通bean:在配置文件中定义bean类型就是返回类型
	3、工厂bean:在配置文件中定义bean类型可以和返回类型不一样
	第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean
	第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型---泛型

IOC操作Bean管理(bean作用域)

	1、在Spring里面设置创建bean实例是单实例还是多实例
	2、在Spring默认配置中默认是单实例对象
	3、如何设置bean是单实例还是多实例
	(1)在Spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
	(2)scope属性值
	第一个值 默认值,singleton,表示单实例对象
	第二个值 prototype,表示是多实例对象
	(3)singleton和prototype区别
	第一 singleton单实例,prototype多实例
	第二 设置scope值是singleton的时候,加载sping配置文件的时候就会创建单实例对象
	    设置scope值是prototype的时候,不是在加载spring配置文件的时候创建对象,而是在调用getBean方法的时候创建多实例对象
	还有两个属性值
	request
	session

IOC操作Bean管理(bean的生命周期)

	1、生命周期
	(1)从对象创建到销毁的过程
	2、bean的生命周期
	(1)通过构造器创建bean实例(无参数构造)
	(2)为bean的属性设置值和对其他bean的引用(调用set方法)
	(3)调用bean的初始化的方法
	(需要进行配置)在实体类中书写方法,在spring配置文件bean中写init-method=“类中写的初始化方法”
	(4)bean可以使用了(对象获取到了)
	(5)当容器关闭的时候,调用bean的销毁的方法
	(需要配置销毁的方法)在实体类中书写方法,在spring配置文件bean中写destory-method=“类中写的销毁方法”
实际销毁还需要在对象使用完成后主动销毁,在第(4)不调用context.close()方法后,会销毁实例并执行所对应的销毁方法
	3、演示生命周期
	4、bean的后置处理器,生命周期有7步
		添加bean的后置处理器(他会给所有bean都添加上):
		实现BeanPostProcessor接口后需要重写2个方法,也就是初始化前(3)和初始化后(5)
	(1)通过构造器创建bean实例(无参数构造)
	(2)为bean的属性设置值和对其他bean的引用(调用set方法)
	(3)把bean实例传递给bean后置处理器的方法(postProcessBeforeInitiallization)
	(4)调用bean的初始化的方法
	(5)把bean实例传递bean后置处理器的方法(postProcessAfterInitiallization)
	(6)bean可以使用了(对象获取到了)
	(7)当容器关闭的时候,调用bean的销毁的方法

IOC操作Bean管理(xml自动装配)

	1、什么是自动装配
	(1)根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
	2、自动装配过程
		bean标签属性autowire,配置自动装配;autowire属性常用2个值:byName根据属性名称注入,byType根据属性类型注入
	(1)根据属性名称自动注入
	(2)根据属性类型自动注入 

IOC操作Bean管理(引入外部的属性文件)

	1、直接配置数据库连接池
	(1)配置德鲁伊连接池
	(2)导入德鲁伊包,spring配置文件中书bean配置数据库
	2、引入外部属性文件配置数据库连接池
	(1)创建外部属性文件,properties格式文件,写数据信息
	(2)把外部properties属性文件引入spring配置文件中
	*引入context命名空间,如上面引入p命名空间一样
	*之后在加入如下代码
<context:property-placeholder location="classpath.properties"/>
	在配置数据库的bean,value书写${}读取值

IOC操作Bean管理(基于注解方式)

	1、什么是注解
	(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...)
	(2)使用注解,注解作用在类上面,方法上面,属性上面
	(3)使用注解的目的:简化xml配置
	2、Spring针对Bean管理中创建对象提供的注解
	(1)@Component()
	(2)@Service(service)
	(3)@Controller(web)
	(4)@Repository(dao)
	*上面四个注解的功能是一样的,都可以用来创建bean实例
	3、基于注解的方式实现对象的创建
	第一步 引入依赖  (spring_aop.jar)
	第二步 开启组件扫描
	*引入context命名空间。然后书写。  
	<context:component-scan base-package=""></context:component-scan>
	base-package书写包名时,可以以多个逗号隔开,或者扫描包上层
	第三步 创建类,在类上添加注解
	4、开启组件扫描的细节问题
	(1)示例1    user-default-filters="false" 表示现在不使用默认filter,自己配置fillter
							context:include-filter   设置扫描哪些内容
	<context:component-scan base-package="" user-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	(2)示例2。context:exclude-filter   设置不扫描哪些内容
	<context:component-scan base-package="">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	5、基于注解方式实现属性注入
	(1)@AutoWired:根据属性类型进行自动装配
		第一步 把service和dao对象创建,在service和dao类添加创建对象注解
		第二步 在service注入dao对象,在service类添加dao类型属性,在属性上面使用注解
	(2)@Qualifier:根据名称进行注入
		这个注解需要和上面的@AutoWired一起使用
	(3)@Resource:可以根据类型注入,可以根据名称注入        是javax中的,建议使用spring同类
	(4)@Value:注入普通类型属性
		@Value(value="abc")
		private String name;
	6、纯注解开发.   一般可以用springboot
	(1)创建配置类,替代xml配置文件。    
	@Configuration
	@ComponentScan(basePackages={'包名'})
	public class SpringConfig(){}
	(2)加载配置类
	ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

AOP

AOP(概念)

	1、什么是AOP
	(1)面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。
	(2)通俗描述:不通过修改源代码的方式,在主干功能里面添加新的功能。(登陆过程中添加权限判断)

AOP(底层原理)

	1、AOP底层使用动态代理
	(1)有两种情况动态代理
	第一种 有接口的情况,使用JDK动态代理
	 - 创建接口实现动态代理,增强类的方法
	第二种 没有接口的情况,使用CGLIB动态代理
	- 创建子类的代理对象,增强类的方法

AOP(JDK动态代理)

	1、使用JDK动态代理,使用Proxy类里面的方法创建代理对象
	(1)调用java.lang.reflect中的Proxy类中的newProxyInstance方法
		方法有三个参数:
		第一参数,类加载器
		第二参数,增强方法所在的类,这个实现的接口,支持多个接口
		第三参数,实现这个接口InvocationHandler,创建代理对象,写增强的方法
	2、编写JDK动态代理代码
	(1)创建接口,书写接口方法
	public interface userDao{
		public int add(int a,int b);
		public String update(String id);
	}
	(2)创建实现类实现接口
	public class userDaoImpl implements userDao{
			public int add(int a,int b){
				return a+b;
			}
			public String update(String id){
				return id;
			}
	}
	(3)创建Proxy代理对象
	public class JDKProxy{
		public static void main(String[] args){
				//创建接口代理对象
				Class[] interfaces = {UserDao.class}
				UserDaoImpl userDao = new UserDapImpl();
				UserDao dao = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
				int result = dao.add(1,2);
				System.out.println("result:"+result);
			}
		class UserDaoProxy implements InvocationHander{
			//把创建的是谁的代理对象,把谁传过来
			//有参数构造传递
			private Object obj;
			public UserDaoProxy(Object obj){
				this.obj = obj;
			}
			//增强的逻辑
			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);
				System.out.println("方法之后执行");
				return res;
			}
		}
		}

AOP(术语)

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

AOP操作(准备)

	1、Spring框架中一般基于AspectJ实现AOP操作
	(1)什么事AspectJ
	*AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作
	2、基于AspectJ实现AOP操作
	(1)基于xml配置文件实现
	(2)基于注解方式实现(使用)
	3、在项目工程中引入AOP相关依赖
	4、切入点表达式
	(1)切入点表达式作用:知道对那个类里面的那个方法进行增强
	(2)语法结构
	execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
	举例1:对com.hc.dao.bookDao类里面的add进行增强
	execution(* com.hc.dao.bookDao.add(..))
	举例2:对com.hc.dao.bookDao类里面的所有方法进行增强
	execution(* com.hc.dao.bookDao.*(..))
	举例3:对com.hc.dao所有类里面的所有方法进行增强
	execution(* com.hc.dao.*.*(..))

AOP操作(AspectJ注解)

	1、创建类(被增强类),在类里面定义方法
		public class User {
			void add(){
				System.out.println("add...");
			}
		}
	2、创建增强类(编写增强逻辑)
	(1)在增强类里面,创建方法,让不同方法代表不同通知类型
		//增强的类
		public class UserProxy(){
			//前置通知
			void before(){
				System.out.println();
			}
		}
	3、进行通知的配置
	(1)在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: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:component-scan base-package="被扫码的包路径"></context:component-scan>
	(2)使用注解创建User和UserProxy对象
	//被增强的类
	@Component
	@Aspect    //注解的作用是生成代理对象
	public class UserProxy{
		public void before(){
			System.out.println("before......");
		}
	}
	(3)在增强类上面添加注解@Aspect     如(2)中
	(4)在spring配置文件中开启生成代理对象
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	4、配置不同类型的通知
	(1)在增强类里面,在作为
	@Component
	@Aspect    //注解的作用是生成代理对象
	public class UserProxy{
		//前置通知
		@Before(value="execution(* com.hc.dao.User.add(..))")
		public void before(){
			System.out.println("before......");
		}
		//返回通知
		@AfterReturning(value="execution(* com.hc.dao.User.add(..))")
		public void afterReturning(){
			System.out.println("afterReturning......");
		}
		//后置通知
		@After(value="execution(* com.hc.dao.User.add(..))")
		public void after(){
			System.out.println("after......");
		}
		//异常通知
		@AfterThrowing(value="execution(* com.hc.dao.User.add(..))")
		public void afterThrowing(){
			System.out.println("afterThrowing......");
		}
		//环绕通知
		@Around(value="execution(* com.hc.dao.User.add(..))")
		public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
			System.out.println("环绕之前......");
			proceedingJoinPoint.proceed();
			System.out.println("环绕之后.....");
		}
		
	}
	5、相同切入点的抽取
	@Pointcut(value="execution(* com.hc.dao.User.add(..))")
	public void pointdemo(){
	}
	@Before(value="pointdemo()")
	public void before(){
		System.out.println("before......");
	}
	6、多个增强类对同一个方法进行增强,设置增强了类优先级
	(1)在增强类上面添加注解@Order(数值类型值),数字类型值越小优先级越高
		@Component
		@Aspect
		@Order(1)
		public class PersonProxy{}
	7、完全使用注解开发
	(1)创建配置类,不需要创建xml配置文件
		@Configuration
		@ComponentScan(basePackages={"com.hc"})
		@EnableAspectJAutoProxy(proxyTargetClass= true)
		public class ConfigAop{}

AOP操作(AspectJ配置文件-了解)

	1、创建两个类,增强类和被增强类,创建方法
	
	2、在Spring配置文件中创建两个类对象
	
	3、在spring配置文件中配置切入点
	<aop:config>
		<!-- 切入点 -->
		<aop:ponintcut id="p" expression="execution(* com.hc.dao.User.add(..))"/>
		<!-- 配置切面 -->
		<aop:aspect ref=“spring中配置的要增强的类的bean的id”>
			<!-- 增强作用在具体方法上 -->
			<aop:before method=“before” pointcut-ref=“p”></aop:before>
		</aop:aspect>
	</aop:config>

Jdbc Template

JdbcTemplate(概念和准备)

	1、什么是JdbcTemplate
	(1)Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作
	2、准备工作
	(1)引入依赖(相比之前多出的依赖)
		druid.jar;
		mysql-connector-java.jar;
		spring-jdbc.jar
		spring-tx.jar(事务依赖)
		spring-orm.jar(若是集成其他框架的依赖)
	(2)在spring配置文件中配置数据库连接池
	<!-- 数据库连接池配置 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destory-method="close">
		<property name="url" value="jdbc:mysql:localhost:3306/user_db"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
	</bean>
	(3)配置JdbcTemplate对象,注入DataSource
	<!-- JdbcTemplate对象 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemple">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	(4)创建service类,创建dao类,在dao注入jdbcTemplate对象
	*配置文件中
	<context:component-scan base-package="com.hc"></context:component-scan>
	@Service
	public class BookService{
		
		@Autowired
		private BookDao bookDao;
	}

	@Repository
	public class BookDaoImpl implements BookDao{
		//注入jdbcTemplate
		@Autowired
		private JdbcTemplate jdbcTemplate;
	}

	public interface BookDao(){
		
	}

JdbcTemplate操作数据库(添加修改和删除)

	1、对应数据库创建实体类
	2、编写service和dao(见上一模块)
	(1)在dao进行数据库添加操作
	(2)调用JdbcTemplate对象里面update方法实现添加修改和删除操作
		jdbcTemplate.update(string sql,object obj)
		第一个参数:sql语句--根据书写不同的sql来执行不同的操作
		第二个参数:参数值对象,可变参数

JdbcTemplate操作数据库(查询返回某个值)

	1、查询表里面有多少条记录,返回是 某个值
	2、queryForObject有两个参数,一个是sql语句,一个是查询值的返回类型
		jdbcTemplate.queryForObject(string sql,Integer.class);

JdbcTemplate操作数据库(查询返回对象)

	1、场景:查询图书详情
	2、jdbcTemplate实现查询:调用含有三个参数的queryForObject
	RowMapper:是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
	jdbcTemplate.queryForObject(sql语句,new BeanPropertyRowMapper<Book> Book.class,sql语句值)

JdbcTemplate操作数据库(查询返回集合)

	1、场景:查询图书列表分页
	2、jdbcTemplate实现查询:调用query,返回的是list集合
	RowMapper:是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
	jdbcTemplate.query(sql语句,new BeanPropertyRowMapper<Book> Book.class,sql语句值)

JdbcTemplate操作数据库(批量操作)

	1、批量操作:操作表里面多条记录
	2、JdbcTemplate实现批量添加
	JdbcTemplate.batchUpdate(String sql,List<Object[]> batchArgs)
	两个参数:一个sql语句。第二个参数:List集合,添加多条记录数据
	3、JdbcTemplate实现批量修改删除
	JdbcTemplate.batchUpdate
	JdbcTemplate.batchDelete  ---传id集合

事务

事务概念

	1、什么是事务
	(1)事务是数据库操作最基本的单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
	(2)典型场景:银行转账
	*lucy转账100元给mary
	*lucy少100元,mary多100元
	2、事务四个特性(ACID)
	(1)原子性(成功都成功,失败都失败)
	(2)一致性(总量不变)
	(3)隔离性(多个事务之间不会产生影响)
	(4)持久性(操作完成后,表中的数据要发生变化)

事务操作(搭建事务操作环境)

	转账操作:
	Service(业务操作):调用的2个方法
	Dao(操作数据库):少钱的方法;多钱的方法
	1、创建数据库表,添加记录
	2、创建service,搭建dao,完成创建对象和注入关系
	(1)service注入dao,在dao注入jdbcTemplate,在jdbcTemplate注入DataSource
	3、在dao创建两个方法:多钱和少钱的方法,在service创建方法(转账的方法)
	//业务层
	@Service
	public class UserService {
		@Autowried
		private UserDao userDao;
		public void accountMoney(){
			userDao.reduceMoney();
			userDao.addMoney();
		}
	}
	//数据库操作层
	@Repository
	public class UserDaoImpl implements UserDao{
		@Autowried
		private JdbcTemplate jdbcTemplate;
		public void reduceMoney(){
			String sql = "update 表名 set user_money = user_money-? where user_name=?";
			jdbcTemplate.update(sql,100,"lucy");
		}
		public void addMoney(){
			String sql = "update 表名 set user_money = user_money+? where user_name=?";
			jdbcTemplate.update(sql,100,"mary");
		}
	}
	//调用层
	@Test
	public class test(){
		ApplicationContextLocation context = new ClassPathXmlApplicationContext("spring的配置文件在src下的路径");
		UserService userService = context.getBean("userService",UserService.class);
		userService.accountMoney();
	}
	4、上面代码,如果正常执行是没有问题的,假如出现异常,
@Service
	public class UserService {
		@Autowried
		private UserDao userDao;
		public void accountMoney(){
			try{
				//第一步 开启事务
				//第二步 进行业务操作
				userDao.reduceMoney();
				//中间模拟异常
				int i= 10/0;
				userDao.addMoney();
				//第三步,没有异常提及事务
			}catch{
				//第四步,出现异常,事务回滚
			}
		}
	}

事务操作(Spring事务管理介绍)

	1、事务添加到javaEE三层结构里面的Service层(业务逻辑层)
	2、在Spring进行事务管理操作
	(1)有两种方式:声明式事务管理(常用)和编程式事务管理(try catch)
	3、声明式事务管理
	(1)基于注解方式(常用)
	(2)基于xml配置文件方式
	4、在Spring进行声明式事务管理,底层使用AOP原理
	5、Spring事务管理API
	(1)提供了一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

事务操作(注解声明式事务管理)

	1、在Spring配置文件中配置事务管理器
		<!-- 创建事务管理器 -->
		<bean id="transactionManager" class="org.springframework.jdbc.dattaSource.DataSourceTransactionManager">
			<!-- 注入数据源 -->
			<property name=“dataSource” ref=“dataSource”></property>
		</bean>
	2、在spring配置文件,开启事务注解
	(1)在spring配置文件中引入事务名称空间(详见上面内容)
	(2)开启事务注解
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
	3、在service类上面(获取service类里面方法上面)添加事务注解
	(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
	(2)如果把这个注解添加类上面,这个类里面的所有方法都添加事务
	(3)如果把这个注解添加方法上面,为这个方法添加事务。
@Service
@Transactional
public class UserService{}

事务操作(声明式事务管理参数配置)

	1、在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数
	2、propagation:事务传播行为
	(1)多事务方法直接进行调用,这个过程中事务是如何进行管理的
	*事务方法:对数据库表数据进行变化的操作
	*spring框架事务传播行为有7种
	REQUIRED:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行。
	REQUIRED_NEW:当前的方法必须启动新事务,并在它自己的事务内运行。如果有事务正在运行,应该将它挂起
	SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
	NOT_SUPPORTED:当前的方法不应该运行在事务中,如果有运行的事务,将它挂起
	MANDATORY:当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
	NEVER:当前的方法不应该运行在事务中。如果有运行的事务,就抛出异常
	NESTED:如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行
	3、ioslation:事务隔离级别
	(1)事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离型产生很多问题
	(2)有三个读问题:脏读、不可重复度、虚(幻)读
	(3)脏读:一个未提交事务读取到另一个未提交的事务
	(4)不可重复读:一个未提交事务读取到另一个已提交的数据
	(5)虚读:一个未提交的事务读取到另一提交事务添加数据
	(6)解决:通过设置事物的隔离级别,解决读的问题
脏读不可重复读幻读
READ UNCOMMITTED(读未提交)
READ COMMITTED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行化)

REPEATABLE READ mysql默认

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation=Isolation.REPEATABLE_READ)
public class UserService{}
	4、timeout:超时时间
	(1)事务需要在一定的时间内进行提交,如果不提交进行回滚
	(2)默认值是-1,设置时间以秒单位进行计算
	5、readOnly:是否只读
	(1)读:查询操作,写:添加修改删除操作
	(2)readOnly默认值false,表示可以查询,可以添加修改删除操作
	(3)设置readOnly值是true,设置成true之后,只能查询
	6、rollbackFor:回滚
	(1)设置查询哪些异常进行事务回滚
	7、norollbackFor:不回滚
	(1)设置出现哪些异常不进行事务回滚

事务操作(XML声明式事务管理)

	1、在Spring配置文件中进行声明
	第一步 配置事物管理器
		<!-- 创建事务管理器 -->
		<bean id="transactionManager" class="org.springframework.jdbc.dattaSource.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:adivce>
	第三步 配置切入点和切面
<!-- 配置切入点和切面 -->
<aop:config>
	<!-- 配置切入点 -->
	<aop:pointcut id="pt" expression="execution(* com.hc.UserServcie.*(..))"/>
	<!-- 配置切面 -->
	<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>

事务操作(完全注解声明式事务管理)

	1、创建配置类,使用配置类替代xml配置文件s

Spring5框架

Spring5新功能

	1、整个Spring5框架的代码基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除
	2、Spring5.0框架自带了通用的日志封装
	(1)Spring5已经移除Log4jConfigListener,官方建议使用Log4j2
	(2)Spring5框架整合Log4j2
	第一步 引入jar包
		log4j-api-2.11.2.jar
		log4j-core-2.11.2.jar
		log4j-slf4j-impl-2.11.2.jar
		slf4j-api-1.7.30.jar
	第二步 创建log4j2.xml文件
	3、Spring5框架核心容器部分支持@Nullable注解
	(1)@Nullable注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数值可以为空
	(2)注解用在方法上面,方法返回值可以为空
	(3)注解使用在方法参数里面,方法参数可以为空
	(4)注解使用在属性上面,属性值可以为空
	4、Spring5核心容器支持函数式风格GenericApplicationContext
@Test
public void testGenericApplicationContext(){
	//创建GenericApplicationContext对象
	GenericApplicationContext context = new GenericApplicationContext();
	//调用context的方法对象注册
	context.refresh();
	context.registerBean("user1",User.class,() -> new User());
	//获取在spring注册的对象
	User user = (User)context.getBean("user1");
	System.out.println(user);
}
	5、Spring5支持整合JUnit5
	(1)整合Junit4
	第一步 引入Spring相关针对测试依赖
	spring-test-5.2.6.jar
	JUnit4的jar
	第二步 创建测试类,使用注解方式完成
@RunWith(SpringJUnit4ClassRunner.class).  //单元测试框架
@ContextConfiguration("classpath:bean1.xml")  //加载配置文件
public class JTest4{
	//这里可以直接注入
}
	(2)Sping5整合JUnit5
	第一步 引入JUnit5的jar包
	第二步 创建测试类,使用注解方式完成
@ExtendWith(SpringExtension.class)
@ContextConfigration("classpath:bean1.xml")
public class JTest5{}
	(3)使用一个复合注解替代上面两个注解完成整合
@SpringJUnitConfig(locations = "classpath:bean1.xml")
public class JTest5{}

Spring5Webflux

	1、SpringWebflux介绍
	基于SpringMVC、SpringBoot、Maven、Java8新特性(不了解的,可以先去了解哈)
	(1)是Spring5添加新的模块,用于web开发的,功能SpringMVC类似的,Webflux使用当前一种比较流行的响应式编程出现的框架
	(2)使用传统web框架,比如SpringMVC,这些基于Servlet容器,Webflux是一种异步非阻塞的框架,异步非阻塞的框架在Servlet3.1以后才支持,核心是基于Reactor的相关API实现的
	(3)解释什么是异步非阻塞
	*异步和同步
	*非阻塞和阻塞
	
	**上面都是针对对象不一样
	
	** 异步和同步针对调用者,调用者发送请求,如果等着对方回应之后才去做其他事情就是同步;如果发送请求之后不等着对方回应就去做其他事情就是异步
	
	** 阻塞和非阻塞针对被调用者,被调用者收到请求之后,做完请求任务之后才给出反馈就是阻塞(需要等待),收到请求之后马上给出反馈然后再去做事情就是非阻塞(不需要等待)
	(4)Webflux特点
	第一 非阻塞式:在有限的资源下,提高系统吞吐量和伸缩性,以Reactor为基础实现响应式编程
	第二 函数式编程:Spring5框架基于java8,Webflux使用Java8函数式编程方式实现路由请求
	(5)比较SpringMVC
	第一 两个框架都可以使用注解方式,都运行在Tomcat等容器中
	第二 SpringMVC采用命令式编程,Webflux采用异步响应式编程
	2、响应式编程
	(1)什么是响应式编程
	响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
	电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似“B1+C1”的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化。
	(2)Java8及其之前版本
	*提供的观察者模式两个类Observer和Observable
public class ObserverDemo extends Observable{
	public static void main(String[] args){
		ObserverDemo observer = new ObserverDemo();
		//添加观察者
		observer.addObserver((o,org)->{
			System.out.println("发生变化");
		});
		observer.addObserver((o,org)->{
			System.out.println("手动被观察者通知,准备改变");
		});
		observer.setChanged(); //数据变化
		observer.notifyObservers();//通知
		
	}
}
	3、响应式编程(Reactor实现)
	(1)响应式编程操作中,Reactor是满足Reactive规范框架
	(2)Reactor有两个核心类,Mono和Flux,这两个类实现接口Publisher,提供丰富操作符。Flux对象实现发布者,返回N个元素;Mono实现发布者,返回0或者1个元素
	(3)Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信号:元素值,错误信号,完成信号,错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者
	(4)代码演示Flux和Mono
	第一步 引入依赖
<dependency>
	<groupId>io.projectreactor</groupId>
	<artifactId>reactor-core</artifactId>
	<version>3.1.5.RELEASE</version>
</dependency>
	第二步 编程代码
public static void main(String[] args){
	//just方法直接声明
	Flux.just(1,2,3,4);
	Mono.just(1);
	//其他的方法
	Integer[] array = {1,2,3,4};
	Flux.fromArray(array);
	List<Integer> list = Arrays.asList(array);
	Flux.fromIterable(list);
	Stream<Integer> stream = list.stream();
	Flux.fromStream(stream);
}
	(5)三种信号特点
	*错误信号和完成信号都是终止信号,是不能共存的
	*如果没有发送任何元素值,而是直接发送错误或者完成信号,表示是空数据流
	*如果没有错误信号,没有完成信号,表示是无限数据流
	(6)调用just或者其他方法只是声明数据流,数据流并没有发出,只有进行订阅之后才会触发数据流,不订阅什么都不会发生的
//just方法直接声明
Flux.just(1,2,3,4).subscribe(System.out::println);
Mono.just(1).subscribe(System.out::println);
	(7)操作符
	*对数据流进行一道道操作,成为操作符,比如工厂流水线
	第一 map 元素映射为新元素
	
	第二 flatMap元素映射为流
			把每个元素转化为流,在整合为一个大流进行返回
	4、SpringWebflux执行流程和核心API
	SpringWebflux基于Reactor,默认使用容器是Netty,Netty是高性能NIO框架,异步非阻塞的框架
	(1)Netty
	*BIO
	*NIO
	(2)SpringWebflux执行过程和SpringMVC相似的
	*SpringWebflux核心控制器DispatcherHandler,实现接口WebHandler
	*接口WebHandler里面有一个方法
	(3)SpringWebflux里面DispatcherHandler,负责请求的处理
	*HandlerMapping:请求查询到处理的方法
	*HandlerAdapter:真正负责请求处理
	*HandlerResultHandler:响应结果处理
	(4)SpringWebflux实现函数式编程,两个接口:RouterFunction(路由处理)和HandlerFunction(处理函数)
	5、SpringWebflux(基于注解编程模型)
	SpringWebflux实现方式有两种:注解编程模型和函数式编程模型
	使用注解编程模型方式,和之前SpringMVC使用相似,只需要把相关依赖配置到项目中,SpringBoot自动配置相关运行容器,默认情况下使用Netty容器
	第一步 创建SpringBoot项目,引入依赖
	第二步 配置启动端口号
	第三步 创建包和其他类
	https://www.bilibili.com/video/BV1Vf4y127N5?p=58&spm_id_from=pageDriver
	*说明
	Springmvc方式实现,同步阻塞方式,基于SpringMVC+Servlet+Tomcat
	SpringWebflux方式实现,异步非阻塞方式,基于SpringWebflux+Reactor+Netty
	6、SpringWebflux(基于函数式编程模型)
	(1)在使用函数式编程模型操作的时候,需要自己初始化服务器
	(2)基于函数式编程模型的时候,有两个核心接口:RouterFunction(实现路由功能,请求转发给对应的handler)和handlerFunction(处理请求生成响应的函数)。核心任务定义两个函数式接口的实现并且启动需要的服务器。

未完待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值