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. tape ——cf

    B. Tape time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  2. kafka环境搭建测试

    一.安装 1. 下载:去kafka官网下载:https://www.apache.org/dyn/closer.cgi?path=/kafka/0.9.0.1/kafka_2.11-0.9.0.1.t ...

  3. Java 8 新特性:2-消费者(Consumer)接口

    (原) 在上一篇,用到过这样一个方法: list.forEach(new Consumer<Integer>() { @Override public void accept(Intege ...

  4. SpringMVC handleMapping映射过程

    初始化IOC容器 Spring初始化的时候会优先初始化自定义的类,下面这个就是 org.springframework.web.servlet.mvc.method.annotation.Reques ...

  5. [TJOI2017]DNA

    嘟嘟嘟 这题怎么想都想不出来,最后还是敲了暴力,喜提40分-- 正解竟然也是暴力-- 用\(s_0\)构造SAM,然后把\(s\)扔上去暴力dfs:记录一个修改次数tot,如果当前不匹配,就tot + ...

  6. C. Nice Garland

    题意: 就是有一串灯分别颜色是R,G,B.要求将每种颜色的灯相隔2个不同的灯.比如,RGR变成RGB才叫好看. 分析: RGB有6种排列,分别是:"RGB", "RBG& ...

  7. Python:Day04

    数学运算符: +  加 -  减 *  乘 **  指数运算 /  除 //  整除 %  取余 比较运算符: >  大于 <  小于 >=  大于等于 <=  小于等于 == ...

  8. Python-wxpy继承关系

    聊天对象 通过机器人对象 Bot 的 chats(), friends(),groups(), mps() 方法, 可分别获取到当前机器人的 所有聊天对象.好友.群聊,以及公众号列表. 而获得到的聊天 ...

  9. (0)HomeAssistant 教程

    国外:https://www.home-assistant.io/components/light.mqtt/ 中国:https://www.hachina.io/docs/890.html

  10. GoldenGate OGG-01032 There Is a Problem in Network Communication Error in Writing to Rmt Remote Trail Rmttrail (Doc ID 1446621.1)

    GoldenGate OGG-01032 There Is a Problem in Network Communication Error in Writing to Rmt Remote Trai ...