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的生命周期*** 依赖注入 注解 ...
随机推荐
- Matlab geom3d函数注释
Matlab geom3d函数解析 geom3d函数库 geom3d库的目的是处理和可视化三维几何原语,如点.线.平面.多面体等.它提供了操作三维几何原语的底层功能,使得开发更复杂的几何算法变得更加容 ...
- mac系统,docker下载安装
1. docker安装文档 2. Docker下安装SQL Server
- React项目中遇到的那些坑
1.react中路由跳转后页面不置顶问题 问题: 从页面A跳转到页面B,页面A滚动到中间位置,跳转后页面B也会在中间位置 解决方法:在顶部组件的生命周期中进行判断,例如 componentWillRe ...
- 2.1.FastDFS-单机拆分版-调度器安装配置
Centos610系列配置 我们在Centos610FastDFS单机模式-FastDFS安装 中已经完成了FastDFS的安装,接下来我们进行FastDFS调度器的安装. 1.找到FastDFS配置 ...
- linux开机启动项问题。6版本与7版本不同之处 。
参考 网址:https://blog.csdn.net/weixin_41909810/article/details/82775247
- 不是充许的静态以太网地址,它与vmware保留的mac地址冲突
不是充许的静态以太网地址,它与vmware保留的mac地址冲突 只需修改vxm文件即可. 第一部,打开vmw的镜像位置,如图. 点击后,打开硬盘,如下 把这个vmx结尾的文件下载,在本地编辑,可用tx ...
- 转专业后补修C语言的一些体会(4)
1.对于文件的打开和关闭操作:首先了解到,C语言将文件分成了两种类型:文本文件和二进制文件.针对这两种文件,各有不同的文件读写方式.在C语言中,文件的操作要借助一个文件指针 即FILE 类型,定义了一 ...
- JQuery 移动端 上下 滑动 切换 插件 pageSlider
HTML <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta ...
- linux(centos6.10)下去掉mysql的强密码验证
vim /etc/my.cnf shift + G 光标移到最下方: o 进入插入模式,同时换行: 添加一行语句: validate_password=OFF 保存退出. servi ...
- 3种使用MQ实现分布式事务的方式
1.保证消息传递与一致性 1.1生产者确保消息自主性 当生产者发送一条消息时,它必须完成他的所有业务操作. 如下图: 这保证消费者接受到消息时,生产者已处理完毕相关业务,也就是1PC的基础. 1.2 ...