Spring之IOC、AOP和事务
IOC
什么是IOC?如果你回答:Spring是个IOC容器,实现原理是反射,没了。这样证明你没有真正理解IOC。
IOC的意思是控制反转,还有个外号叫依赖注入(DI)。为什么起这么晦涩难懂的名字呢?
首先,我们看没有Spring之前,是怎么写代码的。
class SomeController{ // 传统的new一个对象的方式
private SomeService service = new SomeServiceImpl(); public String doSomeThing(){
return service.getSomeThing();
}
}
这种有什么缺点呢?
1. 这个类直接依赖于另一个类的实现(代码耦合)。
2. 如果未来发生了变动,比如变成另一种实现 SomeServiceImplV2,那么我们需要改动代码让它变成一个SomeServiceImplV2对象。
再看用了Spring之后
class SomeController{ // 用了Spring之后
@Autowired
private SomeService service; public String doSomeThing(){
return service.getSomeThing();
}
}
这样做有什么效果呢?
1. 这个类只知道我依赖你哪一个接口,但是具体实现我就不管了。具体最终的实现类是哪一个,由第三方Spring负责注入。
2. 就算未来发生了变动,我们也不需要改动这部分代码。我们只需要告诉第三方Spring:这个接口的实现类变成V2版本了,你注入的时候注意一下。
这个重要的改变就是——控制反转(以前是我主动去控制依赖关系,现在是我被迫接受依赖关系,而这种关系的转变导致了代码的耦合度降低)
而实现控制反转的方式就是依赖注入——在运行期间,由IOC容器动态地将某种依赖关系注入到对象之中
所以
Spring是IOC理论的实践。通过把代码之间的依赖关系交给Spring来管理,解决了代码耦合的问题。
AOP
Spring另一个特性就是AOP(面向切面编程),又是一个晦涩难懂的名词。
先来看一个例子
引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
写个配置类
package com.demo.aop; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("com.demo.aop")
@EnableAspectJAutoProxy
public class SimpleConfig {
}
写个业务接口
package com.demo.aop; public interface SimpleService {
void fun();
}
写个业务实现
package com.demo.aop; import org.springframework.stereotype.Service; @Service
public class SimpleServiceImpl implements SimpleService { public void fun(){
System.out.println("业务方法...");
}
}
写个日志类
package com.demo.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; /**
* 日志类就是一个切面
*/
@Aspect
@Component
public class LogAOP { /**
* 具体业务方法就是切入点
*/
@Pointcut("execution(* com.demo.aop.*.*(..))")
public void aspect(){} /**
* 通知(before/after/around)
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("aspect()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(">>>>>>>>业务方法之前");
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println(">>>>>>>>业务方法之后");
System.out.println(joinPoint + "|Time-Consuming:" + (end-start));
return proceed;
} /**
* 如果出现异常
* @param joinPoint
* @param e
*/
@AfterThrowing(pointcut = "aspect()", throwing = "e")
public void afterException(JoinPoint joinPoint, Exception e){
// TODO
}
}
最后写一个启动方法
package com.demo.aop; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(SimpleConfig.class);
SimpleService bean = context.getBean(SimpleService.class);
bean.fun();
} }
输出:
写这么多,只完成了一件事情——在业务方法前后做一些额外的工作。
那么AOP出现的原因呢?
1. 没有AOP,如果我们想要在一批接口方法执行的前后做一些额外的工作,那么每个方法我们都要写重复的逻辑代码,这可是个体力活。
2. 使用AOP,我们只需要写好额外工作的逻辑,然后配置一下,就可以在一批方法的前后执行我们写好的处理逻辑了。
3. 解决了代码重复的问题,实现了代码复用。
利用AOP可以做很多事情,比如:拦截器、日志、事务管理等等
下面是AOP相关概念
切面(Aspect):要增强的内容,比如上面例子中的日志类
连接点(JoinPoint):从哪里增强,比如上面例子中具体的业务方法就是连接点
切入点(PonitCut):从哪里增强,比如上面例子中具体的业务方法的集合就是切入点
通知(Advise):具体增强的逻辑,比如上面日志类中的方法(@Around标记)
切入点表达式(execution):
常见的比如:
IOC和AOP小结
IOC:对象之间的依赖关系交由容器处理,【降低组件的耦合度】。不用IOC的话,会出现编码依赖问题:程序要分层,层与层之间调用就会存在依赖。一般都是new一个接口的具体实现类,这是硬编码的方式,如果改了需求,还要重新编译class,这也体现不出面向接口编程的好处。最直观的表达就是,IOC让对象的创建不用去new了,而是由spring利用Java的反射机制,根据配置在运行时动态的去创建以及管理对象。
AOP:支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,减少重复代码,从而提供更好的【代码复用】。比如我要在一批方法前后做一些相同的事情,不用AOP的话每个方法前后都要写一堆同样的处理逻辑。
IOC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。
Spring事务
数据库-事务特性(ACID)
⑴ 原子性(Atomicity)
一个事务内所有操作共同组成一个原子包,要么全部成功,要么全部失败。⑵ 一致性(Consistency)
数据库事务的一致性就规定了事务提交前后,永远只可能存在事务提交前的状态和事务提交后的状态,从一个一致性的状态到另一个一致性状态,而不可能出现中间的过程态。⑶ 隔离性(Isolation)
事务的隔离性,基于原子性和一致性,每个事务互不干扰。⑷ 持久性(Durability)
持久性,当一个事物提交之后,数据库状态永远的发生了改变。
数据库-隔离级别
⑴ 读未提交
在这种隔离级别下,查询是不会加锁的,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。⑵ 读已提交
只能读到其它事务已经提交的内容。没有查询加锁,但是却能够避免脏读。可能会产生“不可重复读”、“幻读”。⑶ 可重复读
可以防止“脏读”、“不可重复读”。可能会产生“幻读”。⑷ 串行化
在该级别下,事务顺序执行,不仅避免了脏读,不可重复读,而且避免了幻读。由于加锁,导致大量的请求超时,因此性能会比较低下。脏读:一个事务读到另一个事务未提交的数据
不可重复读:一个事务读到另一个事务已提交的更新的数据。【多次读取数据内容不一致】
幻读:一个事务读到另一个事务已提交的新插入的数据。【多次读取数据数量不一致】。
Spring事务传播(7种)
Propagation.REQUIRED:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是Spring默认的选择。
Propagation.SUPPORTS:支持当前事务,如果没有当前事务,就以非事务方法执行。
Propagation.MANDATORY:支持当前事务,如果没有当前事务,就抛出异常。
Propagation.REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
Propagation.NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
Propagation.NEVER:以非事务方式执行操作,如果当前事务存在则抛出异常。
Propagation.NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
具体使用也是非常简单
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public void addXXX(UserRequest request) {
// 业务逻辑
}
Spring之IOC、AOP和事务的更多相关文章
- Spring学习之AOP与事务
一.概述 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续, ...
- spring中使用aop配置事务
spring的事务配置有5种方式,这里记录其中的一种:基于tx/aop声明式事务配置 在之前spring aop介绍和示例这篇所附代码的基础上进行测试 一.添加save方法 1.在testDao类里添 ...
- Spring(二)--IoC&AOP
IOC 一.IOC概述: 一般指控制反转(inversion of Control),把创建对象的权利交给框架,Ioc容器控制对象,是框架的重要特征,并非是面向对象编程的专用术语.它包括依赖注入(DI ...
- Spring核心--IOC&AOP
Ioc(控制反转) 所谓的控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转. AOP(面向切面编程) ...
- spring的IOC和AOP
spring的IOC和AOP 1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是 ...
- spring的IOC和AOP详细讲解
1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是有这个IOC容器进行产生,同时, ...
- Spring整合JDBC以及AOP管理事务
本节内容: Spring整合JDBC Spring中的AOP管理事务 一.Spring整合JDBC Spring框架永远是一个容器,Spring整合JDBC其实就是Spring提供了一个对象,这个对象 ...
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
- Spring(IOC、AOP和事务)
目录 Spring介绍 Spring IOC 传统代码对象管理的弊端 实现过程 bean标签属性介绍 对象创建方式 工厂bean bean的作用域 SpringBean的生命周期*** 依赖注入 注解 ...
随机推荐
- SQL中AVG、COUNT、SUM、MAX等聚合函数对NULL值的处理
一.AVG() 求平均值注意AVE()忽略NULL值,而不是将其作为“0”参与计算 二.COUNT() 两种用法 1.COUNT(*) 对表中行数进行计数不管是否有NULL 2.COUNT(字段名) ...
- ubuntu 18.04中nginx不能访问软链接目录中的内容
解决办法:以root权限运行nginx,即修改/etc/nginx/nginx.conf中的user www-data为root
- sqlite3 install 和使用
windows: 在 Windows 上安装 SQLite 请访问 http://www.sqlite.org/download.html,从 Windows 区下载预编译的二进制文件. 您需要下载 ...
- mongdb 复制集
步骤: 一.启动三台进程 1../bin/mongod --dbpath=/home/work/app/mongodb/mongodb-linux-x86_64-amazon-3.2.7/data/r ...
- java 责任链模式的三种实现
责任链模式 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止.这里就不再过多的介绍什么 ...
- Vim:Vim入门级配置
转:https://vimjc.com/vimrc-config.html Vim配置文件.vimrc Vim编辑器相关的所有功能开关都可以通过.vimrc文件进行设置. .vimrc配置文件分系统配 ...
- 【渗透测试】NSA Windows 0day漏洞+修复方案
这个漏洞是前段时间爆出来的,几乎影响了全球70%的电脑,不少高校.政府和企业都还在用Windows服务器,这次时间的影响力堪称网络大地震. ------------------------------ ...
- spring boot jpa 复杂查询 动态查询 连接and和or 模糊查询 分页查询
最近项目中用到了jpa,刚接触的时候有些激动,以前的到层忽然不用写sql不用去自己实现了,只是取个方法名就实现了,太惊艳了,惊为天人,但是慢慢的就发现不是这么回事了,在动态查询的时候,不知道怎么操作了 ...
- PW数据库ER图
- 转专业后对于C语言补修的一些体会(2)
第三章,有以下几个比较重要的点: 1. 强制类型转换. 强制类型转换是C语言中一个十分重要的工具,在C语言的使用中,有很多需要用到强制类型转换的地方,比如在除法中,如果想要得到正确的浮点结果,一般要确 ...