Aspectj的使用demo
来源:互联网 发布:js修改css样式 编辑:程序博客网 时间:2024/05/24 06:36
aop编程就是使用了动态代理,但是spring的aop来做面向切面编程会比较麻烦,Aspectj这个包也提供了类似于spring的aop编程,通过注解来配置以及表达式的配置实现并且可以动态给对象添加方法(但是要做类型转换),用起来十分方便
- 介绍下下面5个注解:
1.@Before
前置通知,在方法执行前调用
2.@AfterReturning
返回通知,在方法返回结果之后调用
3.@AfterThrowing
异常通知,在方法抛出异常后调用
4.@After
后置通知,在方法执行完成调用
5.@Around
环绕通知,包含上面4种,围绕着方法执行
- 其他注解:
1.@DeclareParents
用来动态给对象添加属性和方法
2.@Pointcut
定义切入点,用于后面方法表达式的复用
1、2、3、4种通知,调用方法的时候可以自动传入一个JoinPoint 对象,用来获取方法名字或者代理对象或者传入的参数等等,其中第2种AfterReturning可以定义returning = “xxx” 来获取方法调用之后的返回值,第3种AfterThrowing可以定义throwing=”xxx” 来获取抛出的异常对象
5种通知,调用方法适合可以传入一个ProceedingJoinPoint 对象,同上一样可以获取各种信息并且有执行目标对象的方法proceed()
上面的5种的execution表达式都可以配合注解来进行筛选执行方法
execution(* *(..)) && @annotation(myAnnotation)
下面写了个小例子:
首先创建一个目标类:
@Componentpublic class Mytest01 { public String show() { System.out.println("show time"); return "show 执行完成"; }}
创建一个类,里面包含第一种到第四种的注解:
@Component@Aspectpublic class Mytest02 { @Before("execution(* spring06.Mytest01.*(..))") public void before(JoinPoint joinPoint) { showJoinPoint(joinPoint); System.out.println("@Before 执行"); } @AfterReturning(value = "execution(* spring06.Mytest01.*(..))", returning = "result") public void afterReturning(JoinPoint joinPoint, String result) { System.out.println("@AfterReturning 执行,返回值为:" + result); } @AfterThrowing(value = "execution(* spring06.Mytest01.*(..))", throwing = "exception") public void afterThrowing(JoinPoint joinPoint, Exception exception) { System.out.println("@AfterThrowing 执行,异常为:" + exception.getMessage()); } @After("execution(* spring06.Mytest01.*(..))") public void after(JoinPoint joinPoint) { System.out.println("@After 执行"); } /** * joinPoint 常用获取属性 * * @param joinPoint */ private void showJoinPoint(JoinPoint joinPoint) { //获取调用的方法名字 System.out.println("JoinPoint 常用:" + joinPoint.getSignature().getName()); //获取目标类 System.out.println("JoinPoint 常用:" + joinPoint.getTarget()); //获取代理对象 System.out.println("JoinPoint 常用:" + joinPoint.getThis()); //获取参数 System.out.println("JoinPoint 常用:" + joinPoint.getArgs()); }}
创建另一个类,里面只包含第五种的注解,以及DeclareParents和Pointcut注解:
@Component@Aspectpublic class Mytest03 { /** * 给被切面编程的Mytest01对象添加NewServiceImpl里面的参数和方法 */ @DeclareParents(value = "spring06.Mytest01", defaultImpl = NewServiceImpl.class) private NewService service; /** * 这里是定义一个切入点,后面的方法都可以直接引用 */ @Pointcut("execution(* spring06.Mytest01.*(..))") public void myPoint() { } @Around("myPoint()") public Object around(ProceedingJoinPoint proceedingJoinPoint) { System.out.println("@Around 开始"); Object result = null; try { result = proceedingJoinPoint.proceed(); } catch (Throwable throwable) { System.out.println("@Around 获取出异常:" + throwable.getMessage()); } finally { System.out.println("@Around 执行结束"); } System.out.println("@Around 开始返回结果"); return result; }}
DeclareParents注解需要用到的接口:
public interface NewService { String newShow(String show);}
DeclareParents注解需要用到的实现类:
public class NewServiceImpl implements NewService { public String newShow(String show) { System.out.println("这是调用的newShow,value = " + show); return show; }}
创建一个main入口:
public static void main(String[] args) { AbstractApplicationContext appContext = new ClassPathXmlApplicationContext("application06.xml"); Mytest01 test = appContext.getBean(Mytest01.class); test.show(); NewService service = (NewService) test; service.newShow("new"); appContext.registerShutdownHook(); }
xml配置:
<context:component-scan base-package="spring06"/><aop:aspectj-autoproxy/>
测试前4中注解,先注释掉Mytest03的Aspect注解,执行main方法,结果如下:
测试第5种的环绕注解,注释掉Mytest02的Aspect注解,执行main方法,结果如下:
小demo完成,我们可以使用它去做一些日志的处理比如Controller被访问前后都打印日志,就可以用aspectj来完成,可以参考java注解结合aspectj AOP进行日志打印
- Aspectj的使用demo
- AspectJ 的使用
- 基于IDEA的aspectj项目demo
- 基于@AspectJ的AOP的使用
- spring3.0 aspectj 的配置与使用
- 使用Spring AOP 的@AspectJ记录日志
- Spring-AOP切面+Aspectj框架的使用
- 使用AspectJ的AOP配置管理事务配置
- 使用AspectJ基于注解的Aop
- Spring Boot AspectJ AOP的使用
- Spring 3.0.6 Aspectj的配置和使用 The import org.aspectj cannot be resolved
- Spring AOP使用整理:使用@AspectJ风格的切面声明
- Spring AOP使用整理:使用@AspectJ风格的切面声明
- AspectJ使用经验
- AspectJ使用经验
- AspectJ使用经验
- spring AspectJ 基本使用
- 使用@AspectJ注解
- DNS服务及其管理
- PyTorch学习之路(level2)——自定义数据读取
- 第6次C练习
- C++中extern "C"的使用
- VMware无法连接 MKS:套接字连接尝试次数太多正在放弃
- Aspectj的使用demo
- execute immediate v_sql用法
- [LeetCode] 33. Search in Rotated Sorted Array
- JS基础
- 20171125 变量类型的大小
- PAT 1074
- 二维数组中的查找
- 第十五章作业
- 浅谈C语言中如何取随机数