Spring事务管理主要包括3个接口,Spring的事务主要是由他们三个共同完成的。
声明式事务管理使用了AOP面向切面编程实现的,本质就是在目标方法执行前后进行拦截。在目标方法执行前加入或创建一个事务,在执行方法执行后,根据实际情况选择提交或是回滚事务。
Spring事务的隔离级别
基于代理(Proxy)的AOP实现
- 调用者Beans - 即调用发起者,它只知道目标方法所在Bean,并不清楚代理以及Advice的存在
- 目标方法所在Bean - 被调用的目标方法
- 生成的代理 - 由Spring AOP为目标方法所在Bean生成的一个代理对象
- Advice - 切面的执行逻辑
IOC(控制反转):全称为:Inverse of Control。从字面上理解就是控制反转了,将对在自身对象中的一个内置对象的控制反转,反转后不再由自己本身的对象进行控制这个内置对象的创建,而是由第三方系统去控制这个内置对象的创建。
DI(依赖注入):全称为Dependency Injection,意思自身对象中的内置对象是通过注入的方式进行创建。
依赖注入通常有三种:
1.工厂模式,这个很明显,在各种BeanFactory以及ApplicationContext创建中都用到了;
2.模版模式,这个也很明显,在各种BeanFactory以及ApplicationContext实现中也都用到了;
3.代理模式,在Aop实现中用到了JDK的动态代理;
4.单例模式,这个比如在创建bean的时候。
5.Tomcat中有很多场景都使用到了外观模式,因为Tomcat中有很多不同的组件,每个组件需要相互通信,但又不能将自己内部数据过多地暴露给其他组件。用外观模式隔离数据是个很好的方法。
6.策略模式在Java中的应用,这个太明显了,因为Comparator这个接口简直就是为策略模式而生的。Comparable和Comparator的区别一文中,详细讲了Comparator的使用。比方说Collections里面有一个sort方法,因为集合里面的元素有可能是复合对象,复合对象并不像基本数据类型,可以根据大小排序,复合对象怎么排序呢?基于这个问题考虑,Java要求如果定义的复合对象要有排序的功能,就自行实现Comparable接口或Comparator接口.
7.原型模式:使用原型模式创建对象比直接new一个对象在性能上好得多,因为Object类的clone()方法是一个native方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
8.迭代器模式:Iterable接口和Iterator接口 这两个都是迭代相关的接口,可以这么认为,实现了Iterable接口,则表示某个对象是可被迭代的;Iterator接口相当于是一个迭代器,实现了Iterator接口,等于具体定义了这个可被迭代的对象时如何进行迭代的
Spring支持如下5种作用域:
singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
spring中:
1.使用@Component注解配置管理
在各个实现类前加上注解
@Component //其它组件 属性:value指定bean的id. @Controller//web @Service//service @Repository//dao
2.Spring DI 注解配置
在各个方法前加上注解@Value()
注入复杂类型:
(1) @Autowired
(2) @Autowired
@Qualifier(“accountDao2”)
//同时根据 数据类型 和 bean的id 名称进行查找
(3) @Resource(name=“bean的id”) //javax.annotation
注意:JDK9版本,javax包不会自动导入,需要单独导入如下依赖:
springmvc中:
@RequestMapping //作用:建立url-method映射 修饰类、方法 ***** value、path、method、params、headers
@RequestParam //作用:获取指定的请求参数 修饰方法参数 **** value、required
@RequestBody //作用:获取请求体 k=v&k=v 修饰方法参数 ***
@RequestHeader //作用:获取指定的请求头 修饰方法参数 *
@PathVariable //作用:获取url中的占位符 修饰方法参数 /user/{uid} restful
@CookeValue //作用:获取指定名称的Cookie 修饰方法参数 .
@ModelAttribute //作用:先于请求方法执行,预加载 修饰方法、方法参数
@SessionAttributes //作用:往session域存入数据 修饰类
DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于 mvc 模式中的 c, dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求, dispatcherServlet 的存在降低了组件之间的耦合性。
HandlerMapping:处理器映射器
HandlerMapping 负责根据用户请求找到 Handler 即处理器, SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等
#将传入的数据都当成一个字符串,会对传入的数据自动加上引号;
$将传入的数据直接显示生成在SQL中
注意:使用 $ 占位符可能会导致SQL注入攻击,能用#的地方就不要使用 $
写order by 子句的时候应该用 $ 而不是#
所谓的动态 SQL ,指的是 SQL 语句是在程序运行期间动态生成的。MyBatis 的强大特性之一便是它的动态 SQL。在 MyBatis 中,支持通过 XML 标签配置的方式实现动态 SQL
if 标签 where标签 forEach标签
使用mappper代理方式要遵循什么规范?
1.接口名要和对应的映射文件的名称相同(只是后缀名不同)
2.接口的全限定名要和mapper映射文件的namespace 一致
3.接口中的方法名要和mapper映射文件中的唯一标识的id相同
4.要在同一目录下面(可以创建一个源文件夹,然后创建一个和src目录下面相同的包,已达到xml和接口分离的作用)
5: 接口的方法返回类型和mapper 映射文件返回的类型一致
6 接口的方法参数类型和mapper 映射文件输入类型要一致
mybatis整个调用执行过程:
1.加载配置并初始化:即mybatis主配置文件,mapper配置文件及注解配置。其中将SQL配置的信息加载为一个个MapperStatement对象(传入参数映射配置、执行的SQL语句、结果映射配置)。
2.接收调用请求:接收到传入的参数和需要执行的SQL的ID,将请求传递给下层的数据处理层进行处理。
3.处理操作请求:执行器Executor处理接收到接口层传递的SQL的ID和传入参数,根据ID查找对应的MapperStatement,解析MapperStatement对象,得到需要执行的SQL语句并注入传入的参数。获取到数据库连接,将最终的SQL语句到数据库执行,并得到结果。根据MapperStatement对象中的结果映射配置对得到的结果进行转换处理,得到最终的结果。最后释放资源并返回结果到上层。
关于动态代理和CGLIB这两种方式的简要总结如下:
JDK动态代理(Dynamic Proxy)
基于标准JDK的动态代理功能
只针对实现了接口的业务对象
CGLIB
通过动态地对目标对象进行子类化来实现AOP代理,上面截图中的SampleBean E n h a n c e r B y C G L I B EnhancerByCGLIB EnhancerByCGLIB1767dd4b即为动态创建的一个子类
需要指定@EnableAspectJAutoProxy(proxyTargetClass = true)来强制使用
当业务对象没有实现任何接口的时候默认会选择CGLIB