Aop一般有以下常用注解:
@Aspect: 该注解是把此类声明为一个切面类。
@Before: 该注解是声明此方法为前置通知 (目标方法执行前就会先执行被此注解标注的方法)
@After: 该注解是声明此方法为后置通知 (目标方法执行完之后就会执行被此注解标注的方法)
@After: 该注解是声明此方法为返回通知 (目标方法正常执行返回后就会执行被此注解标注的方法)
@AfterThrowing: 该注解是声明此方法为异常通知 (目标方法在执行出现异常时就会执行被此注解标注的方法)
@Around: 该注解是环绕通知是动态的,可以在前后都设置执行
@PointCut: 该注解是声明一个公用的切入点表达式(通知行为的注解的都可以直接拿来复用)
如果是注解式开发还会用到@EnableAspectJAutoProxy: 该注解是声明这个配置类使用注解式的AOP(还有一种古老的方式是在xml文件里声明开启AOP)
什么时候会用到AOP: 写日志,事务等,就是一些不是业务逻辑代码要做的事就交给AOP来完成。
二丶案例演示AOP的使用下面一个例子日志输出的功能来演示:
(1)步骤一: 用maven创建一个项目,pom.xml导入所需的依赖:spring容器依赖,Aop依赖,单元测试依赖。
(2)步骤二: 创建四个类: 启动配置类: MyConfig
业务逻辑类: MyService
日志切面类: MyLog
测试类: MyTest
(3)步骤三: 编写测试代码调式AOP功能怎么实现的
具体步骤分析:
步骤一:
项目的搭建好的包级目录如下:
pom.xml文件的主要依赖项如下:
junit
junit
4.11
test
org.junit.jupiter
junit-jupiter
RELEASE
compile
org.springframework
spring-context
5.2.12.RELEASE
org.springframework
spring-aspects
5.2.5.RELEASE
步骤二: 写好所需要的类
MyConfig启动配置类如下:
//配置类
@Configuration
@EnableAspectJAutoProxy //开启Aop注解功能
public class MyConfig {
//向容器中注册: 日子切面类
@Bean
public MyLog myLog(){
return new MyLog();
}
//向容器中注册: 业务逻辑类
@Bean
public MyService myServie(){
return new MyService();
}
}
MyService业务逻辑类如下:
//业务逻辑类
public class MyService {
//除法方法,返回两个数相除的结果
public int divide(int a, int b){
return a / b;
}
}
MyLog日志切面类如下:
//日志切面类
//得加上此注解此切面类才会生效
@Aspect
public class MyLog {
//抽取公共的切入点表达式
//该表达式表明MyService类下的所有方法都加上aop功能
@Pointcut("execution(public int org.com.MyService.*(..))")
public void pointCut(){};
//在目标方法之前切入
//复用上面定义的pointCut()方法上的切入点表达式
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
//获取目标方法名 (单纯取出来而已下面没有用到这个变量)
String methodName = joinPoint.getSignature().getName();
//获取目标方法参数列表 (下面有输出这个)
Object[] args = joinPoint.getArgs();
System.out.println("除法运行...参数列表是: {" + Arrays.asList(args) + "}");
}
//在目标方法之后切入
@After("pointCut()")
public void logEnd(){
System.out.println("除法结束...");
}
//在目标方法正常返回切入
//result是目标方法正常返回的返回值
@AfterReturning(value = "pointCut()", returning = "result")
public void logReturn(Object result){
System.out.println("除法正常返回...运行结果: { " + result + " }");
}
//在目标方法异常时切入
//exception是目标方法异常的异常对象
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void logException(Exception exception){
System.out.println("除法异常...异常信息: {" + exception+ "}");
}
}
测试类: 该类的测试方法未完成,在步骤三来完成并说明最终测试情况
//测试类
public class MyTest {
//正常测试
@Test
public void test01(){}
//故意传入错误的参数测试(除法运算时分母不能为0,但强行这样做康康会怎么样)
@Test
public void test02(){}
}
}
步骤三:
1: 正常的测试:传入的值都是能正常进行除法运算的,观察控制输出,是不是切面类的前置通知,后置通知,正常返回通知等方法是不是都执行了,测试代码如下:
//正常测试
@Test
public void test01(){
//通过配置类启动容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
//用id取出业务逻辑类的bean
MyService myService = (MyService) applicationContext.getBean("myService");
//调用此bean的divide方法观察控制台的输出信息,其中传入的参数进行除法运算是正常的
myService.divide(1, 1);
}
控制台输出如下:
分析: 可见切面类的aop功能真的生效了
2: 异常的测试:故意传一个分母为0这种情况,康康切面类的异常通知方法会不会执行
//故意传入错误的参数测试(除法运算时分母不能为0,但强行这样做康康会怎么样)
@Test
public void test02(){
//通过配置类启动容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
//用id取出业务逻辑类的bean
MyService myService = (MyService) applicationContext.getBean("myService");
//调用此bean的divide方法观察控制台的输出信息,其中传入的分母参数为 0
try{
//分母故意传个 0 康康会不会执行切面类的异常通知方法
myService.divide(1, 0);
}catch (Exception e){
}
}
控制台输出如下:
分析: 除法异常,异常通知方法确实执行了!
三丶总结注解式的Aop就是好用和简单,很多繁琐的事就可以交给Aop来做了,Aop实现的三部曲分别是:
1. 创建业务类。
2. 创建切面类,其中切面类上加@Aspect注解说明该类是个切面类,方法上加上想要的通知功能的注解。
3. 创建配置类,加上@EnableAspectJAutoProxyz注解来开启Aop注解功能,注册之前创建的业务类和切面类。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)