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. 关于this的理解

    var o = { a:10, b:{ a:12, fn:function(){ console.log(this.a); //undefined console.log(this); //windo ...

  2. linux crontab定时器

    1.查看linux是否有crontab指令  如果没有安装crontab指令 yum install -y vixie-cron yum -y install crontabs 2.设置开机自启 ch ...

  3. tensorflow错误:Shape (10, ?) must have rank at least 3

    错误的代码 outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32) 错误原因: 该错误的意思是传入的数据集X的维度只有二维,而tf.nn.d ...

  4. Ubuntu 14.04 安装 CUDA 问题及解决

    本文安装环境: - 双显卡: intel 集显 + nvidia 独显 - Ubuntu 14.04.4 - CUDA 8.0.44 1. Deb 安装包是个坑 (不要用这种方法!) 使用 Deb 安 ...

  5. Spring容器的简单实现(IOC原理)

    引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢? 一.容器是装东西的,就像你家的水缸,你吃饭的碗等等. java中能作为容器的有很 ...

  6. 深入源码理解ThreadLocal和ThreadLocalMap

    一.ThreadLoacl的理解: 官方的讲: ThreadLocal是一个本地线程副本变量工具类,主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰 通俗的讲: Thre ...

  7. JVM深度解析

    JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java语言的 ...

  8. List,DataTable实现行转列的通用方案

    最近在做报表统计方面的需求,涉及到行转列报表.根据以往经验使用SQL可以比较容易完成,这次决定挑战一下直接通过代码方式完成行转列.期间遇到几个问题和用到的新知识这里整理记录一下. 阅读目录 问题介绍 ...

  9. flink1.7自定义source实现

    flink读取source data 数据的来源是flink程序从中读取输入的地方.我们可以使用StreamExecutionEnvironment.addSource(sourceFunction) ...

  10. java并发线程池---了解ThreadPoolExecutor就够了

    总结:线程池的特点是,在线程的数量=corePoolSize后,仅任务队列满了之后,才会从任务队列中取出一个任务,然后构造一个新的线程,循环往复直到线程数量达到maximumPoolSize执行拒绝策 ...