AspectJProxyFactory,可能大家对这个比较陌生,但是@Aspect这个注解大家应该很熟悉吧,通过这个注解在spring环境中实现aop特别的方便。

AspectJProxyFactory这个类可以通过解析@Aspect标注的类来生成代理aop代理对象,对开发者来说,使创建代理变的更简洁了。

先了解几个概念

文中会涉及几个概念,先了解一下。

target

用来表示目标对象,即需要通过aop来增强的对象。

proxy

代理对象,target通过aop增强之后生成的代理对象。

AspectJ是什么?

AspectJ是一个面向切面的框架,是目前最好用,最方便的AOP框架,和spring中的aop可以集成在一起使用,通过Aspectj提供的一些功能实现aop代理变得非常方便。

AspectJ使用步骤

1.创建一个类,使用@Aspect标注

2.@Aspect标注的类中,通过@Pointcut定义切入点

3.@Aspect标注的类中,通过AspectJ提供的一些通知相关的注解定义通知

4.使用AspectJProxyFactory结合@Ascpect标注的类,来生成代理对象

案例

来个类

package com.javacode2018.aop.demo9.test1;

public class Service1 {

    public void m1() {
System.out.println("我是 m1 方法");
} public void m2() {
System.out.println(10 / 0);
System.out.println("我是 m2 方法");
}
}

通过AspectJ来对Service1进行增强,来2个通知,一个前置通知,一个异常通知,这2个通知需要对Service1中的所有方法生效,实现如下:

package com.javacode2018.aop.demo9.test1;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; //@1:这个类需要使用@Aspect进行标注
@Aspect
public class Aspect1 { //@2:定义了一个切入点,可以匹配Service1中所有方法
@Pointcut("execution(* com.javacode2018.aop.demo9.test1.Service1.*(..))")
public void pointcut1() {
} //@3:定义了一个前置通知,这个通知对刚刚上面我们定义的切入点中的所有方法有效
@Before(value = "pointcut1()")
public void before(JoinPoint joinPoint) {
//输出连接点的信息
System.out.println("前置通知," + joinPoint);
} //@4:定义了一个异常通知,这个通知对刚刚上面我们定义的切入点中的所有方法有效
@AfterThrowing(value = "pointcut1()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
//发生异常之后输出异常信息
System.out.println(joinPoint + ",发生异常:" + e.getMessage());
} }

@1:类上使用@Aspect标注

@2:通过@Pointcut注解标注在方法上面,用来定义切入点

@3:使用@Before标注在方法上面,定义了一个前置通知,通过value引用了上面已经定义的切入点,表示这个通知会对Service1中的所有方法生效,在通知中可以通过这个类名.方法名()引用@Pointcut定义的切入点,表示这个通知对这些切入点有效,若@Before@Pointcut在一个类的时候,直接通过方法名()引用当前类中定义的切入点

@4:这个使用@AfterThrowing定义了一个异常通知,也是对通过value引用了上面已经定义的切入点,表示这个通知会对Service1中的所有方法生效,若Service1中的方法抛出了Exception类型的异常,都会回调afterThrowing方法。

来个测试类

package com.javacode2018.aop.demo9;

import com.javacode2018.aop.demo9.test1.Aspect1;
import com.javacode2018.aop.demo9.test1.Service1;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; public class AopTest9 {
@Test
public void test1() {
try {
//对应目标对象
Service1 target = new Service1();
//创建AspectJProxyFactory对象
AspectJProxyFactory proxyFactory = new AspectJProxyFactory();
//设置被代理的目标对象
proxyFactory.setTarget(target);
//设置标注了@Aspect注解的类
proxyFactory.addAspect(Aspect1.class);
//生成代理对象
Service1 proxy = proxyFactory.getProxy();
//使用代理对象
proxy.m1();
proxy.m2();
} catch (Exception e) {
}
}
}

运行输出

前置通知,execution(void com.javacode2018.aop.demo9.test1.Service1.m1())
我是 m1 方法
前置通知,execution(void com.javacode2018.aop.demo9.test1.Service1.m2())
execution(void com.javacode2018.aop.demo9.test1.Service1.m2()),发生异常:/ by zero

AspectJProxyFactory原理

@Aspect标注的类上,这个类中,可以通过通过@Pointcut来定义切入点,可以通过@Before@Around@After@AfterRunning@AfterThrowing标注在方法上来定义通知,定义好了之后,将@Aspect标注的这个类交给AspectJProxyFactory来解析生成Advisor链,进而结合目标对象一起来生成代理对象,大家可以去看一下源码,比较简单,这里就不多解释了。

最新文章

  1. [转载]C/C++可变参数之va_start和va_end使用详解
  2. 听声辨位识DUMP
  3. Hadoop虽然强大,但不是万能的(CSDN)
  4. js输出26个字母两种方法(js fromCharCode的使用)
  5. shell MAC 地址 校验
  6. C#.net拖拽实现获得文件路径
  7. 开源 侧滑 和 Tab滑动翻页 控件
  8. ORA-16014: 日志 1 的序列号 242 未归档, 没有可用的目的地
  9. Netty那点事: 概述, Netty中的buffer, Channel与Pipeline
  10. Spring Boot 学习(1)
  11. Python核心编程笔记--私有化
  12. python基础——面向对象进阶下
  13. 【Python3爬虫】你会怎么评价复仇者联盟4?
  14. Python脱产8期 Day12 2019/4/26
  15. Reading List on Automated Program Repair
  16. 【转载】如何让图片按比例响应式缩放、并自动裁剪的css技巧
  17. SSD安装记录
  18. zabbix 实现对服务器的负载监控
  19. POI简易帮助文档系列--读取Excel文件
  20. 计算概论(A)/基础编程练习1(8题)/3:晶晶赴约会

热门文章

  1. idea Mark Directory as 的几种文件类型
  2. let that = this用法解析
  3. SpringBoot中使用@ConfigurationProperties提示:Configuration Annotation Processor not found in classpath
  4. 【数据结构&算法】11-树基础&二叉树遍历
  5. Python基础(使用模块)
  6. centos7.6自动化安装mysql5.5
  7. Java 获取PDF数字签名证书信息
  8. [cf1270I]Xor on Figures
  9. [atARC113F]Social Distance
  10. generator函数与async/await