AOP,面向切面编程,它能把与核心业务逻辑无关的散落在各处并且重复的代码给封装起来,降低了模块之间的耦合度,便于维护。具体的应用场景有:日志,权限和事务管理这些方面。可以通过一张图来理解下:

Spring AOP可以通过注解和xml配置的方式来实现,下面我们讲解下这两种不同的用法。

1.注解的方式

定义一个切面Operator

/**
* 定义一个切面Operator:包含切入点表达式和通知
*/ @Component
@Aspect
public class Operator { //定义切入点表达式
@Pointcut("execution(* com.demo.aop..*.*(..))")
public void pointCut() { }; //以下都为通知
//前置通知:在目标方法调用前执行
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("AOP before advice ...");
} //在目标方法正常执行后做增强处理
@AfterReturning("pointCut()")
public void doAfterReturn(JoinPoint joinPoint) {
System.out.println("AOP after return advice ...");
} //环绕通知:在目标方法完成前后做增强处理
@Around("pointCut()")
public void around(ProceedingJoinPoint pjp) {
System.out.println("AOP Around before...");
try {
pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("AOP Aronud after...");
} //在目标方法完成后做增强处理,无论目标方法是否成功完成
@After("pointCut()")
public void doAfter(JoinPoint joinPoint) {
System.out.println("AOP after advice ...");
} //用来处理发生的异常
@AfterThrowing(pointcut="pointCut()",throwing="error")
public void afterThrowing(JoinPoint joinPoint,Throwable error){
System.out.println("AOP AfterThrowing Advice..." + error);
} }

定义UserService类

@Service("userService")
public class UserService { public void add(){
System.out.println("UserService add()");
} public boolean delete(){
System.out.println("UserService delete()");
return true;
} }

执行以下代码:

@Test
public void testAop(){
@SuppressWarnings("resource")
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");//解析注册beanDefinition,然后实例化bean,再初始化bean
UserService userService = (UserService) applicationContext.getBean("userService");
userService.add();
}

输出结果是:

AOP Around before...
AOP before advice ...
UserService add()
AOP Aronud after...
AOP after advice ...
AOP after return advice ...

所以由此,我们可以总结出通知的执行顺序:

无异常情况:around before -->before-->目标方法-->around after-->after-->afterReturn

有异常情况:around before -->before-->目标方法-->around after-->after-->afterThrowing

2.xml配置的方式

xml配置的方式我们以日志为例

在xml中添加配置信息

    <aop:config>
<aop:aspect id="loggerAspect" ref="logger">
<aop:around method="record"
pointcut="(execution(* com.demo.aop..*.add*(..))
or execution(* com.demo.aop..*.update*(..))
or execution(* com.demo.aop..*.delete*(..)))
and !bean(logService)" />
</aop:aspect>
</aop:config>

新建Log实体类

public class Log {

    private Integer id;

    //操作名称,方法名
private String operName; //操作人
private String operator; //操作参数
private String operParams; //操作结果 成功/失败
private String operResult; //结果消息
private String resultMsg; //操作时间
private Date operTime = new Date(); public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getOperName() {
return operName;
} public void setOperName(String operName) {
this.operName = operName;
} public String getOperator() {
return operator;
} public void setOperator(String operator) {
this.operator = operator;
} public String getOperParams() {
return operParams;
} public void setOperParams(String operParams) {
this.operParams = operParams;
} public String getOperResult() {
return operResult;
} public void setOperResult(String operResult) {
this.operResult = operResult;
} public String getResultMsg() {
return resultMsg;
} public void setResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
} public Date getOperTime() {
return operTime;
} public void setOperTime(Date operTime) {
this.operTime = operTime;
}

创建切面Logger类

@Component("logger")
public class Logger { @Autowired
private LoggerService loggerService; //记录操作日志
public Object record(ProceedingJoinPoint joinPoint) throws Throwable{
Log log = new Log(); try {
String methodName = joinPoint.getSignature().getName(); //目标方法方法名称
Object[] args = joinPoint.getArgs();
String argsStr = Arrays.toString(args); //请求参数
log.setOperator("admin");
log.setOperName(methodName);
log.setOperParams(argsStr);
Object returnObj = joinPoint.proceed();
if(null != returnObj){
log.setOperResult(returnObj.toString());
}else{
log.setOperResult(null);
}
log.setResultMsg("success");
} catch (Exception e) {
log.setResultMsg("fail");
}finally{
loggerService.save(log);
}
return null;
} }

创建保存日志信息的类LoggerService

@Service("loggerService")
public class LoggerService {
public void save(Log log){
System.out.println("save log ...");
}
}

创建UserService类

@Service("userService")
public class UserService { public void add(){
System.out.println("UserService add()");
} public boolean delete(){
System.out.println("UserService delete()");
return true;
} }

运行以下代码:

@Test
public void testAopLog(){
@SuppressWarnings("resource")
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");//解析注册beanDefinition,然后实例化bean,再初始化bean
UserService userService = (UserService) applicationContext.getBean("userService");
userService.add();
}

输出结果:

UserService add()
save log ...

以上就是AOP注解和xml配置两种不同的用法,我们需要继续了解:AOP有哪些应用场景以及如何使用的,实现原理,和spring AOP源码分析。接下来我将逐个的去介绍这一块。

spring AOP的用法的更多相关文章

  1. spring aop execution用法

    代码结构: 1. "execution(* com.ebc..*.*(..))" 与 "execution(*  com.ebc..*(..))" 2019-0 ...

  2. Spring AOP 和 动态代理技术

    AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...

  3. Spring Aop(一)——Aop简介

    转发地址:https://www.iteye.com/blog/elim-2394629 1 Aop简介 AOP的全称是Aspect Oriented Programming,翻译成中文是面向切面编程 ...

  4. Java Spring AOP用法

    Java Spring AOP用法 Spring AOP Java web 环境搭建 Java web 项目搭建 Java Spring IOC用法 spring提供了两个核心功能,一个是IoC(控制 ...

  5. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  6. Spring AOP切点表达式用法总结

    1. 简介        面向对象编程,也称为OOP(即Object Oriented Programming)最大的优点在于能够将业务模块进行封装,从而达到功能复用的目的.通过面向对象编程,不同的模 ...

  7. Spring AOP 中@Pointcut的用法

    Spring Aop中@pointCut的用法,格式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? nam ...

  8. Spring AOP中JoinPoint的用法

    Spring JoinPoint的用法 JoinPoint 对象 JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的 ...

  9. 《Spring 5官方文档》 Spring AOP的经典用法

    原文链接 在本附录中,我们会讨论一些初级的Spring AOP接口,以及在Spring 1.2应用中所使用的AOP支持. 对于新的应用,我们推荐使用 Spring AOP 2.0来支持,在AOP章节有 ...

随机推荐

  1. 想要快速上手 Spring Boot?看这些教程就足够了!

    1.项目名称:分布式敏捷开发系统架构 项目简介:基于 Spring + SpringMVC + Mybatis 分布式敏捷开发系统架构,提供整套公共微服务服务模块:集中权限管理(单点登录).内容管理. ...

  2. Python:Day41 http、css

    HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则. 2.请求协议 请求协议的格式如下: 请求首行: // ...

  3. Go调试工具—— Delve

    参考https://github.com/go-delve/delve 安装 首先你必须有等于或高于1.8版本的Go,我的版本是: userdeMBP:go-learning user$ go ver ...

  4. ORA-4031 During Startup Nomount using RMAN without parameter file (PFILE) (Doc ID 1176443.1)

    ORA-4031 During Startup Nomount using RMAN without parameter file (PFILE) (Doc ID 1176443.1) APPLIES ...

  5. jenkins+svn+python+appium启动+mail+html报告

    第一步:jenkins从svn中获取最新的测试代码 1.jenkins启动,进入jenkins目录,使用“java -jar jenkins.war”启动(安装后,jenkins已自启动,不用再自己启 ...

  6. Luogu5221 Product

    Luogu5221 Product 求 \(\displaystyle\prod_{i=1}^n\prod_{j=1}^n{\frac{\operatorname{lcm}(i,\ j)}{\gcd( ...

  7. linux内存源码分析 - 内存回收(整体流程)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 当linux系统内存压力就大时,就会对系统的每个压力大的zone进程内存回收,内存回收主要是针对匿名页和文 ...

  8. jquery()后续版本中,live()取消后使用on()实现功能写法

    今天做项目想用live()功能,写完打开浏览器发现报错 然后查了查发现自己用的是jquery是jquery-2.1.1.min.js,而jquery早就取消了live()方法,在后续版本里都已经没有使 ...

  9. 对Android系统权限的认识

    Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制 Android系统权限相关的内容 (一)linux文件系统上的权限 -rwxr-x--x ...

  10. JS /javascript 解除网页屏蔽右键(无法复制)的代码

    javascript:(function() { function R(a){ona = "on"+a; if(window.addEventListener) window.ad ...