【Spring实战】—— 13 AspectJ注解切面
时间:2022-04-22
本文章向大家介绍【Spring实战】—— 13 AspectJ注解切面,主要内容包括如果需要使用around只需要在切面中添加如下的代码就可以了:、对于参数的传递的通知,也与原先通过配置的差不多、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
前面了解了典型的AOP基于配置的使用方法,下面介绍下如何依赖于注解来实现AOP。 基于注解降低了配置文件的复杂程度,但是引入了程序间的耦合,其中的优劣待用户自己判断了。 需要注意的是,确定AspectJ与JDK之间的版本,否则会报错,详情请见。
首先看一下基于注解的切面类,这时的切面不仅仅是一个POJO类了,与AOP进行了紧密的耦合。但是配置过程和方式都与原来的方式差不多。
package com.spring.test.chap44;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class Audience {
@Pointcut("execution(* com.spring.test.chap44.Instrumentalist.perform(..))")
public void performance(){}
@Before("performance()")
public void takeSeats(){
System.out.println("takeSeats()");
}
@Before("performance()")
public void turnOffCellphones(){
System.out.println("turnOffCellphones()");
}
@AfterReturning("performance()")
public void applaud(){
System.out.println("applaud()");
}
@AfterThrowing("performance()")
public void demandRefund(){
System.out.println("demandRefund()");
}
}
接下来是其他一些必不可少的类:
切点接口类:
package com.spring.test.chap44;
public interface Performer {
public void perform();
}
切点实现类:
package com.spring.test.chap44;
import org.springframework.stereotype.Component;
@Component
public class Instrumentalist implements Performer{
public void perform() {
System.out.println("__________ perform ___________");
}
}
测试类:
package com.spring.test.chap44;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Performer performer = (Performer)ctx.getBean("xingoo");
performer.perform();
}
}
下面是重点的配置文件
此时的配置文件注意要使spring知道哪一个是普通的bean,哪一个是通知。因此需要加上一个属性,保证AOP自动的识别通知。
<aop:aspectj-autoproxy proxy-target-class="true"/>
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="xingoo" class="com.spring.test.chap44.Instrumentalist"/>
<bean id="audience" class="com.spring.test.chap44.Audience" />
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
执行结果如下:
turnOffCellphones()
takeSeats()
__________ perform ___________
applaud()
如果需要使用around只需要在切面中添加如下的代码就可以了:
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint joinpoint){
try{
System.out.println("11111");
long start = System.currentTimeMillis();
joinpoint.proceed();
long end = System.currentTimeMillis();
System.out.println("time—— "+(end-start)+" millinseconds");
System.out.println("22222");
}catch(Throwable t){
System.out.println("in watchPerformance Throwable()");
}
}
对于参数的传递的通知,也与原先通过配置的差不多
在切面中配置好切点的方法,注意带上参数
private String str;
@Pointcut("execution(* com.spring.test.chap44.Instrumentalist.perform(String)) && args(str)")
public void performance(String str){}
@Before("performance(str)")
public void takeSeats(String str){
System.out.println("takeSeats()"+str);
}
其他的基本都不用动了,只要把切点的方法,修改成带有参数的就可以了
public class Instrumentalist implements Performer{
public void perform(String str) {
System.out.println("__________ perform ___________" + str);
}
}
- iOS @property探究(二): 深入理解你要知道的@property都在这里
- iOS block探究(一): 基础详解你要知道的block都在这里
- 在不动用sp_configure的情况下,如何 =》去掉列的自增长,并保留原数据
- iOS runtime探究(一): 从runtime开始理解面向对象的类到面向过程的结构体你要知道的runtime都在这里
- iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
- SpringMVC 启动流程及相关源码分析你要知道的SpringMVC启动流程和源码分析都在这里
- iOS runtime探究(四): 从runtiem开始实践Category添加属性与黑魔法method swizzling你要知道的runtime都在这里
- C# 复制PDF页面到另一个PDF文档
- Java8 Lambda表达式与Stream API (一):Lambda表达式你要知道的Java8 匿名内部类、函数式接口、lambda表达式与Stream API都在这里
- iOS runtime探究(五): 从runtime开始深入weak实现机理你要知道的runtime都在这里
- Java8 Lambda表达式与Stream API (二): Stream API的使用你要知道的Java8 匿名内部类、函数式接口、lambda表达式与Stream API都在这里
- Python Garbage Collection 与 Objective-C ARCPython GC 与 Objective-C ARC
- SpringMVC DispatcherServlet执行流程及源码分析你要知道的SpringMVC DispatcherServlet执行流程及源码分析都在这里
- iOS runtime探究(三): 从runtime开始理解OC的属性property你要知道的runtime都在这里
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- MQ 系列之 ActiveMQ 基本使用
- 使用脚本定时备份 MySQL 数据库
- 解决数独问题用人工智能还是量子计算?
- Leetcode 39. 组合总和(dfs)
- 短视频APP制作,设置高斯模糊
- 使用 Sunny-Ngrok 将内网程序发布到外网
- Leetcode 17. 电话号码的字母组合 (dfs)
- Java实现md5和base64加密解密的示例代码
- Spring 基于 XML 的 AOP
- SpringBoot 集成 Apache Camel FTP 实现文件同步
- Spring 基于 XML 的 IOC
- 初识 Spring
- Leetcode 55. 跳跃游戏 (贪心)
- SpringBoot 报 No operations allowed after connection closed 异常解决办法
- Leetcode 15 三数之和(双指针,去重)