Spring
2021-12-28 10:29:19 70 举报
AI智能生成
spring核心技术IOC、AOP、事务、整合mybatis
作者其他创作
大纲/内容
框架前言<br>
框架怎么学
框架是一个软件<br>1、知道框架能做什么,mybatis--访问数据库,对表中数据执行CRUD<br>2、框架的语法,框架要完成一个功能,需要一定的步骤支持。<br>3、工作两三年后,框架的内部实现,框架内部怎么做,原理是什么。<br>4、通过学习,可以实现一个框架。
SSH:Struct2+Spring+Hibernate(全自动)<br>SSM:SpringMVC(将前端数据传给后台)+Spring(容器框架)+Mybatis(半自动持久层框架)<br>SSJ:Spring+SpringMVC+SpringJDBC
Spring Boot:一个快速开发的脚手架,基于SpringBoot可以快速的开发单个微服务。<br>约定大于配置!<br>学习SpringBoot的前提,需要完全掌握Spring和SpringMVC!承上启下的作用!<br>Spring Cloud:是基于SpringBoot实现的,大多数公司都在使用SpringBoot进行快速开发。<br>
简介
Spring(创始人:Rod Johnson )最早:interface21框架<br>Spring:开源免费的、轻量级的、非侵入式的容器(一个服务器软件,一个框架)!<br> 类与类之间的管理,帮助开发人员创建对象,管理对象间的关系。<br>
依赖:class a中使用class b的属性或方法,叫class a依赖class b<br>注:maven管理外部依赖,spring管理项目内部依赖
什么是spring
是一个框架,核心技术是ioc、aop,能实现那模块之间,类之间的解耦合。
Spring的优势
1、轻量:Spring核心功能所需的jar总共3M左右<br>2、针对接口编程,解耦合<br>通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring控制,避免硬编码造成的过度耦合。用户也不必为单例模式类、属性文件解析等底层需求编写代码,可以更专注于上层的应用。<br>3、AOP编程的支持<br>通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现。<br>4、方便集成各种优秀框架<br>
什么样的对象放入到容器中
dao类、service类、controller类、工具类
spring中的对象默认都是单例的,在容器中叫这个名称的对象只有一个
Spring容器中的bean可以分为5个范围:<br>(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。<br>(2)prototype:为每一个bean请求提供一个实例。<br>(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。<br>(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。<br>(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。<br>
不放到spring容器的对象
实体类对象,实体类数据来自数据库的
servlet,listener,filter等
怎么使用spring<br>
spring是一个容器,把项目中用的对象放到容器中
1、使用xml配置文件,使用<bean>
2、注解
xml与注解的区别<br>
xml更加万能,适用于任何场合,维护简单方便。<br>注解不是自己类使用不了,维护相对复杂。
xml与注解最佳实践
xml用来管理bean;<br>注解只负责完成属性的注入。<br>
实际应用<br>
注解为主,配置文件为辅
让容器完成对象的创建,对象之间关系的管理(属性赋值)
我们在程序中获取 要使用的对象
使用spring框架的步骤
1、加入spring-context依赖(间接加入了spring-aop依赖)<br><!--IOC--><br> <dependency><br> <groupId>org.springframework</groupId><br> <artifactId>spring-context</artifactId><br> <version>5.3.13</version><br> </dependency><br>
2、创建类:接口,实现类,没有接口的类
3、创建spring的配置文件,使用<bean>声明对象
4、使用容器中的对象,通过ApplicationContext接口和它的实现类<br>ClassPathXmlApplicationContext的方法getBean()
核心技术
IOC(Inversion of Controller)(控制反转)<br>
控制反转是一个理论,概念,思想。<br>描述的:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是其它外部资源完成。<br>控制:创建对象,对象的属性赋值,对象之间的关系管理。<br>反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。由容<br> 器代替开发人员管理对象。创建对象,给属性赋值。<br>正转:由开发人员在代码中使用new构造方法创建对象,开发人员主动管理对象。<br>psmv(String args){<br> Student stu=new Student(); //在代码中创建对象,正转<br>}<br>
IOC由Spring来创建,管理,装配,IOC就是典型的工厂模式,通过sessionFactory去注入实例。
为什么使用IOC
目的是减少对代码的改动,也能实现不同的功能,实现业务对象之间的解耦合。<br>例如:能实现service和dao对象之间的解耦合。<br>
java中创建对象有哪些方式
1、构造方法,new Student()<br> 2、反射<br> 3、序列化<br> 4、克隆<br> 5、动态代理<br> 6、IOC:容器创建对象<br>
IOC的体现
servlet <br> 1、创建类继承HttpServlet<br> 2、在web.xml注册servlet,<br> 使用<servlet-name>myservlet</servlet-name><br> <servlet-class>com.kx.controller.MyServlet</servlet-class><br> 3、未创建Servlet对象,没有MyServlet myservlet=new MyServlet()<br> 4、Servlet是Tomcat服务器给你创建的。Tomcat也叫容器<br> Tomcat作为容器:里面存放的有Servlet对象,Listener,Filter对象<br>
IOC的技术实现<br>
DI(Dependency Injection依赖注入)是IOC的技术实现。<br>DI:只需要在程序中提供要使用的对象名称即可,至于对象如何在容器中创<br>建,赋值,查找都有容器内部实现。 <br>依赖:bean对象的创建依赖于容器。<br>注入:bean对象中的所有属性,由容器来注入<br>
DI给属性赋值
一个类中的属性:简单类型、对象类型、集合类型
1、属性注入(set注入)(*):spring调用类的set方法实现属性赋值<br>
1、简单类型的set注入<br><property name="属性名" value="属性值">
例:<br><--<br> id:bean的唯一标识符,也就是相当于我们学的对象名<br> class:bean对象所对应的全限定名:包名+类型<br> name:也就是别名,而且name可以同时取多个别名<br>--><br><bean name="car1,car2" class="com.kx.beans.Car" ><br> <property name="brand" value="suv"/><br></bean>
2、引用类型的set注入<br><property name="属性名" ref="bean的id">
例:<br><bean name="person" class="com.kx.beans.Person"><br> <property name="name" value="zhangsan"/><br> <property name="age" value="18"/><br> <property name="car" ref="car"/><br></bean><br>
<!--内部bean--><br><bean name="person1" class="com.kx.beans.Person"><br> <property name="name" value="zhnagsan"/><br> <property name="age" value="18"/><br> <property name="car"><br> <bean class="com.kx.beans.Car"><br> <property name="brand" value="suv"/><br> <property name="crop" value="浙江"/><br> <property name="price" value="100000"/><br> <property name="maxSpeed" value="30"/><br> </bean><br> </property><br></bean>
<!--级联属性--><!--级联属性配置:Car中要有set get方法--><br><bean name="person2" class="com.kx.beans.Person"><br> <property name="name" value="zhangsan"/><br> <property name="age" value="18"/><br> <property name="car" ref="car"/><br> <property name="car.maxSpeed" value="230"/><br></bean>
2、构造注入(如果写了带参构造器,必须写出无参构造):spring调用有参构造方法
1、<constructor-arg>的name属性,name表示构造方法的形参名
例:<br><!--构造器注入--><br><bean name="car" class="com.kx.beans.Car"><br> <constructor-arg name="brand" value="audi"/><br> <constructor-arg name="crop" > //字面值<br> <!--cdata特殊字符--><br> <value><![CDATA[<上海>]]></value><br> </constructor-arg><br> <constructor-arg name="price" value="200000"/><br></bean><br>
2、<constructor-arg>的index属性,表示构造方法形参的位置,从0开始
3、自动注入
由spring根据某些规则,给引用类型完成赋值,常用的由byName,byType
1、byName:按名称注入,java类中引用类型的属性名和spring容器中bean的【id】一样,<br>数据类型一样,这样bean赋值给引用类型
2、byType:按类型注入,Java类中引用类型的是【数据类型】和spring容器中的【class】是同源关系的,<br>这样bean就能赋值给引用类型
Spring是使用的DI实现了IOC的功能,Spring底层创建对象,使用的是反射机制。
常用注解
注解的使用步骤
1、加入依赖:spring-context,间接加入spring-aop
2、在类中加入注解
3、在spring的配置文件中,加入组件扫描器的标签<context:component-scan base-package="包名">
1、@Component:标识了一个受Spring管理的组件,有几个衍生注解,在web开<br> 发中,会按照mvc三层架构分层。<br>2、@Repository:dao对象,用来访问数据库<br>3、@Service<br>4、@Controller<br>5、@Value:简单类型的属性赋值<br>
6、@Autowired:引用类型的赋值,byType。<br>如果需要自动装配上名字属性,则需要通过@Qualifier(value="xxx")
使用:<br>直接在属性上使用即可!也可以在实体类set方法上使用!<br>使用Autowired可以不用编写Set方法了,前提是这个自动装配的属性在IOC(Spring)容器中存在<br>,且符合byName。<br>
例:<br>@Autowired(required = false)说明这个对象可以为null,否则为空。<br>@Qualifier(value = "jemi")<br>private Cat cat;
7、@Resource:引用类型的赋值,默认通过byName的方式实现,<br>如果找不到名字,则通过byType实现!
例:<br>@Resource(name="kaixin")<br>private Dog dog;<br>
8、@Nullable:字段可以为null。
IOC能实现业务对象之间的解耦合<br>例:service和dao对象之间的解耦合
AOP(Aspect Oriented Program)(面向切面编程)<br>(OOP面向对象编程的升级)<br>
底层是动态代理
1、JDK代理
使用jdk反射包中的类实现创建代理对象的功能
实现接口的动态代理。<br>InvocationHandler接口———调用处理程序<br> Method<br> Proxy类——————————代理<br>
2、CGLIB(Code generation Library)代理<br>
使用第三方的工具库,实现代理对象的创建
继承类的动态代理。<br>
应对有些类没有实现接口,采用继承,所以方法不能是final<br>MethodInterceptor方法拦截器接口、Enhancer增强器<br>
扩展
静态代理
角色分析<br>
抽象角色:一般会使用接口或者抽象类来解决。
真实角色:被代理的角色
代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作。
客户:访问代理对象的人
代码步骤
接口——>真实角色——>代理角色——>客户端访问代理角色
代理模式的好处
可以使真实角色的操作更加纯粹!不用去关注一些公共的业务<br> 公共业务就交给代理角色!实现了业务的分工!<br> 公共业务发生扩展的时候,方便集中管理!
缺点
一个真实角色就会产生一个代理角色,代码量会翻倍~开发效率会变低。
aop:看做是动态代理的规范化,把实现动态代理的步骤进行了一个规范,定义
aop作用
1)在目标类源代码不改变的情况下,增加功能。<br>
2)减少代码的重复
3)专注业务逻辑代码<br>
4)解耦合,给你的业务功能和日志,事务等非业务功能分离
在Spring中的作用:提供声明式事务,允许用户自定义切面。<br>
什么时候考虑使用aop技术
1、给一个系统中存在的类修改功能,但是原有类的功能不完善<br>但你还没有源代码,使用aop就增加功能。
2、给项目中的多个类增加一个相同的功能,使用aop
@Override<br> public void doSome() {<br>// System.out.println("方法的执行时间"+new Date());<br> ServiceTools.doLog();<br> System.out.println("执行业务方法doSome");<br><br> //方法最后,提交事务<br>// System.out.println("方法执行完毕后,提交事务");<br> ServiceTools.doTrans();<br> }<br><br> @Override<br> public void doOther() {<br>// System.out.println("方法的执行时间"+new Date());<br> ServiceTools.doLog();<br> System.out.println("执行业务方法doOther");<br><br>// System.out.println("方法执行完毕后,提交事务");<br> ServiceTools.doTrans();<br> }
3、给业务增加方法,日志输出
aop中概念
1、aspect:切面,横切关注点被模块化的特殊对象。即它是一个类。<br> 表示增强的功能,就是一堆代码,完成某个功能,非业务功能,常见的切面<br> 功能有日志,事务,统计信息,参数检查,权限验证
2、advice:通知,切面必须要完成的工作。即它是类中的一个方法。<br> 通知表示切面功能执行的时间。
3、pointcut:切入点,切面通知执行的位置。<br>指多个连接点方法的集合。(多个方法)<br>
其它术语
target:目标,被通知对象。<br>给哪个类的方法增加功能,这个类就是目标对象。<br>
Proxy:代理,向目标对象应用通知之后创建的对象。
joinpoint:连接点,与切入点匹配的执行点。<br>连接业务方法和切面的位置,即类中的业务方法。(一个方法)<br>
aop的实现
1、spring:spring在内部实现了aop规范,能做aop的工作。<br>
2、aspectJ:开源的专门做aop的框架。(强大)
1、使用注解就可以实现aop功能
@Aspect:是aspectj框架中的注解。
作用:表示当前类是切面类。<br>
切面类:是用来给业务方法增加功能的类,在这个类中有切面的功能代码
2、使用xml配置文件中的标签实现aop功能
aspectJ框架的使用
1、表示切面的执行时间(规范中叫做Advice(通知;增强)),使用的通知注解
1)@Before:前置通知<br>在目标方法之前先执行切面的功能
例:<br>@Before("execution(public int ..CaculatorImpl.*(int,int))")
2)@AfterReturning:后置通知<br>
属性
1、value切入点表达式
2、returning自定义的变量,表示目标方法的返回值的。<br>
特点<br>
1、能够获取到目标方法的返回值,可以根据这个返回值做不同的处理功能<br>
2、可以修改此返回值<br>
例:<br>@AfterReturning(value = "execution(* *..SomeServiceImpl.doOther(..))", returning = "res")<br>
3)@Around:环绕通知<br>环绕通知等同于jdk动态代理,InvocationHandler接口<br>
属性<br>
ProceedingJoinPoint等同于Method<br>
特点
1、功能最强的通知,在目标方法的前后都能增强功能
2、控制目标方法是否被调用执行(控制目标方法的访问)<br>
3、修改返回值(能修改原来的目标方法的执行结果,影响最后的调用结果)<br>
应用
经常做事务,在目标方法前开启事务,执行目标方法,在目标方法后提交事务
4)AfterThrowing:异常通知<br>
属性
1、value切入点表达式
2、throwing 自定义变量,表目标方法抛出的异常对象。<br>变量名必须和方法的参数名一致
特点<br>
1、在目标方法抛出异常时执行的
2、可以做异常的监控程序,监控目标方法执行时是否有异常<br>如果有异常,可以发送邮件,短信进行通知<br>
5)@After:最终通知,总会被执行的代码
6)@PointCut:定义和管理切入点的辅助注解
1、定义切入点:<br>@Pointcut("execution(* *..SomeServiceImpl.doSecond(..))")<br> public void myPt() {<br> //无需代码<br> }
2、调用切入点:<br>@Before(value = "myPt()")<br> public void myBefore() {<br> System.out.println("前置通知,在目标方法之前先执行");<br> }<br>
7)代理的使用方式
1、如果目标类有接口,框架使用jdk动态代理<br>
2、如果目标类没有接口,默认使用的cglib动态代理
3、有接口也可以强制使用cglib动态代理
2、表示切面执行的位置,使用的是切入点表达式<br>
*:0至多个参数<br>..: 用在方法参数中,表示任意多个参数<br> 用在包名后,表示当前包及其子包路径
切入点表达式:execution(访问修饰符 返回值 包名.类名.方法名(方法参数)异常)
Spring整合MyBatis
整合的想法:使用spring的IOC技术,<br>把mybatis框架中使用的对象交给spring统一创建和管理。<br>spring是容器,存放service、dao、工具类等对象
mybatis.xml
<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br></settings><br><typeAliases><br> <typeAlias type="com.kx.entity.Student" alias="student"/><br></typeAliases><br><mappers><br><!-- <mapper resource="com/kx/dao/StudentDao.xml"/>--><br> <package name="com.kx.dao.StudentDao"/><br></mappers><br>
交给spring的mybatis对象
1、数据源DataSource,使用阿里的Druid连接池
<!--<br> 把数据库的配置信息写在一个独立的文件中,编译修改数据库的配置内容<br> spring知道jdbc.properties文件的位置<br> --><br> <context:property-placeholder location="classpath:jdbc.properties"/>
<!--声明数据源DataSource,作用是连接数据库的--><br> <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><br> <!--set注入给DruidDataSource提供连接数据库信息--><br> <property name="url"<br> value="${jdbc.url}"/> <!--setUrl--><br> <property name="username" value="${jdbc.username}"/><br> <property name="password" value="${jdbc.password}"/><br> <property name="maxActive" value="${jdbc.max}"/><br> </bean><br>
2、SqlSessionFactory对象,使用SqlSessionFactoryBean在内部创建SqlSessionFactory
<!--声明的是mybatis中提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionFactory--><br> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><br> <!--set注入,把数据库连接池赋给了dataSource属性<br> configLocation属性是Resource类型,读取配置文件<br> 它的赋值,使用value,指定文件路径,使用classpath:表示文件的路径<br> --><br> <property name="dataSource" ref="myDataSource"/><br> <!--mybatis主配置文件的位置--><br> <property name="configLocation" value="classpath:mybatis.xml"/><br> </bean><br>
3、Dao代理对象,使用MapperScannnerConfigure,<br>在此类内部调用getMapper(),创建接口的Dao对象
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><br> <!--指定SqlSessionFactory对象的id--><br> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/><br> <!--指定包名,包名是dao接口所在的包名<br> MapperScannerConfigurer会扫描此包中所有接口,<br> 把每个接口都执行一次getMapper()方法,得到每个接口的dao对象。<br> 创建好的dao对象放到spring的容器中的.dao对象的默认名称是 接口名首字母小写<br> --><br> <property name="basePackage" value="com.kx.dao"/><br> </bean>
4、Service对象
<!--声明service--><br> <bean id="studentService" class="com.kx.service.impl.StudentServiceImpl"><br> <property name="studentDao" ref="studentDao"/><br> </bean>
Spring对JDBC的支持(spring-jdbc)
1、JdbcTemplate类被设计成为线程安全的,由它来更新查询数据库。(推荐)<br>
2、JdbcDaoSupport类(不推荐)简化DAO实现,该类声明了一个jdbcTemplate。
3、具名参数NamedParameterJdbcTemplate,易于维护,可读性高。
<!--配置jdbcTemplate--><br><bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><br> <property name="dataSource" ref="dataSource"/><br></bean><br><bean name="deptDao" class="com.kx.jdbc.DeptDAO"><br> <property name="dataSource" ref="dataSource"/><br></bean><br><br><bean name="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"><br> <constructor-arg ref="dataSource"/><br></bean>
Spring中事务处理(spring-tx)
事务
什么是事务
事务指一组sql语句集合,这些sql语句的执行是一致的,作为一个整体执行。
事务管理来确保数据的完整性和一致性。<br>Atomicity:事务是个原子操作,由一系列动作完成,事物的原子性确保动作要么都完成,要么都失败。<br>Consistency:一旦所有事务动作完成,事务就被提交,数据和资源处于一种满足业务规则的一致性状态中。<br>Isolation:可能有许多事务会同时处理相同的数据,因此每个事务都应与其他事务隔离开来,防止数据损坏。<br>Durability:一旦事务完成,无论发生什么系统错误,结果不受影响。通常情况下,事物的结果被写到持久化存储器中。<br>
事务管理
1、编程式事务管理
2、声明式事务管理(提倡)(SpringAop支持声明式事务管理)<br>声明式事务:把事务相关的资源和内容都提供给spring,<br>spring就能处理事务提交,回滚了。几乎不用代码。
什么时候用到事务
操作涉及多表或多个sql语句的insert、update、delete。<br>要么都成功要么都失败。
在java代码中事务应该放在service类的业务方法上,<br>因为业务方法会调用多个dao方法,执行多个sql语句。
通常使用JDBC访问数据库,<br>用mybatis访问数据库怎么处理事务
jdbc访问数据库,处理事务:conn.commit();conn.rollback();
mybatis访问数据库,处理事务:SqlSession.commit();SqlSession.rollback();
hibernate访问数据库,处理事务:Session.commit();Session.rollback();
在3问题中事务的处理方式,有什么不足
1)不同的数据库访问技术,处理事务的对象,方法不同,需要了解不同数据库<br> 访问技术使用事务的原理。
2)掌握多种数据库中事务的处理逻辑。何时提交或回滚事务。
3)处理事务的多种方法。
总结:多种数据库的访问技术,有不同的事务处理机制,对象,方法。
处理事务,需要怎么做,做什么
spring处理事务的模型,使用的步骤都是固定的。<br>把事务使用的信息提供给spring即可。
并发事务导致:脏读、不可重复读、幻读
事务隔离级别
read_uncommitted:为解决任何并发问题。
read_committed:解决脏读
repeatable_read(MySQL默认):解决脏读、不可重复读、存在幻读
serializable:串行化。不存在并发问题。(安全性高,性能低)
事务的超时时间
表示一个方法最长的执行时间,如果方法执行时超过了<br> 时间,事务就回滚。单位秒,整数值,默认是-1。
事务的7个传播行为,表示业务方法调用时<br>
Propagation.REQUIRED(默认)<br>
Propagation.REQUIRES_NEW<br>
Propagation.SUPPORTS
Propagation.MANDATORY <br>Propagation.NOT_SUPPORTED<br>Propagation.NEVER<br>Propagation.NESTED
方法提交事务,回滚事务的时机
1、当你的业务方法执行成功,没有抛异常,当方法执行完毕,spring在方法<br> 执行后提交事务
2、业务方法抛出运行时异常,spring执行回滚,调用事务管理器的rollback<br> 运行时异常的定义:RuntimeException和它的子类都是运行时异常,例如<br> NullPointException、NumberFormatException
3、业务方法抛出非运行时异常,主要是受查异常和error时,提交事务<br> 受查异常:写代码时,必须处理的异常:IOException、SQLException
spring框架中提供的事务处理方案
1、适合中小项目使用的,注解方案<br>spring框架自己用aop实现给业务方法增加事务的功能,使用@Transactional注解增加事务。<br>@Transactional是spring框架自己的注解,放在public方法上方。表示当前方法具有事务。<br>可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等。<br>
使用@Transactional的步骤:<br> 1)需要声明事务管理器对象<br> <bean id="xx" class="DataSourceTransactionManager"><br> 2)开启事务注解驱动,告诉spring,我要使用注解的方式管理事务。<br> spring使用aop机制,创建@Transactional所在的类代理对象,给方法加入事务<br> 的功能。<br> spring给业务方法加入事务:在业务方法执行前,先开启事务,在业务方法之<br> 后提交或回滚事务,使用aop环绕通知<br> @Around("增加的事务功能的业务方法名称")<br> Object myAround(){<br> //开启事务,spring来开启<br> try{<br> buy(1001,10);<br> spring的事务管理.commit();<br> }catch(Exception e){<br> spring的事务管理.rollback();<br> }<br> }<br> 3)在方法上方加注解
@Transaction
<!--使用spring事务管理器--><br><!--1、声明事务管理器--><br> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br> <!--连接的数据库,指定数据源--><br> <property name="dataSource" ref="myDataSource"/><br> </bean><br><!--2、开启事务注解驱动,告诉spring使用注解管理事务,创建代理对象<br> transaction-manager:事务管理器对象的id<br> --><br> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
//自定义的运行时异常<br>public class NotEnoughException extends RuntimeException{<br> public NotEnoughException() {<br> }<br> public NotEnoughException(String message) {<br> super(message);<br> }<br>}
@Transactional(<br> propagation = Propagation.REQUIRED,<br> isolation = Isolation.DEFAULT,<br> readOnly = false,<br> rollbackFor = {<br> //两个自定义的异常类<br> NullPointerException.class,<br> NotEnoughException.class<br> }<br> )
2、适合大型项目,有很多的类,方法,需要大量的配置事务,使用aspectj框架功能:<br>在是spring配置文件中声明类,方法需要的事务。<br>这种方式业务方法和shi'wu'pei'zhi事务配置完全分离。
实现步骤:都是在xml配置文件中实现。<br> 1)要使用的是aspectj框架,需要加入spring-aspects依赖<br> 2)声明事务管理器对象<br> <bean id="xx" class="DataSourceTransactionManager"><br> 3)声明方法需要的事务类型(配置方法的事务属性:隔离级别,传播行为,超时)<br> 4)配置aop:指定哪些类需要创建代理
Spring-Web
实现步骤:<br>1、创建maven,web项目<br>2、加入依赖<br> 拷贝my07依赖、加jsp,servlet依赖<br>3、拷贝my07代码和配置文件<br>4、创建一个jsp发起请求,有参数id,name,email,age<br>5、创建Servlet,接收请求参数,调用Service,调用dao完成注册<br>6、创建一个jsp作为显示结果页面
拓展
1、Spring的IOC理解
IOC指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,<br>并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。<br> DI依赖注入,和控制反转是同一个概念的不同角度的描述,即应用程序在运行时依赖IOC容器来动态注入对象需要的外部资源。<br>最直观的表达:IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反射机制,<br>根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。
2、Spring的AOP理解
抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,<br>同时提高了系统的可维护性。可用于权限认证、日志、事务处理。<br> AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;<br>动态代理则以Spring AOP为代表(JDK动态代理和CGLIB动态代理)。
3、Spring Bean的生命周期
先说Servlet的生命周期:实例化、初始init、接收请求service、销毁destroy
1、实例化Bean<br>对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,<br>实例化所有的bean。
2、设置对象属性(依赖注入)<br>实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 <br>以及通过BeanWrapper提供的设置属性的接口完成依赖注入。
3、处理Aware接口<br>Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean。
4、BeanPostProcessor<br>如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,<br>那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
5、InitializingBean 与 init-method<br>如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
6、如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Objectobj, String s)方法;<br>由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;
7、DisposableBean<br>当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;<br>
8、destroy-method<br>如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
4、Spring框架中都用到了哪些设计模式
(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
(2)单例模式:Bean默认为单例模式。
(3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
(4)模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
(5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,<br>所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener。
0 条评论
下一页