首先看java配置类,请忽略的declaredFeature,那个是还没走通的一个实验要用到的bean。
@Aspect注解定义的类也声明为bean。
package com.glodon.springdemo6;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AppConfig {
@Bean
public RetryComp retryComp(){
return new RetryComp();
}
@Bean
public Aspects aspects(){
return new Aspects();
}
@Bean
public DeclaredFeature declaredFeature(){
return new DeclaredFeature();
}
}
以下是定义的切片:
whenRetryMethodExecuted()其实就相当于一个标签,可以替换掉上面那一大坨切点的表达式。当有切点表达式需要复用的时候,就比较合适定义一个空函数作为标签复用。后面的args是当切面的逻辑中有需要被代理对象传递过来的参数的时候,加上args可以接受参数。几种不同的advice注解都在下面列着了,基本上看名字就知道是用来干啥的。@Around注解表示环绕通知,joinpoint调用的proceed方法其实就是被代理类执行的逻辑,可以在其前后加上需要接入的逻辑。不好意思那么多专有名词我实在记不住。
package com.glodon.springdemo6;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class Aspects {
@Pointcut("execution(* com.glodon.springdemo6.RetryComp.retryMethod(..)) && args(maxNum)")
public void whenRetryMethodExecuted(int maxNum){}
@Before("whenRetryMethodExecuted(maxNum)")
public void getReadyForExecution(int maxNum){
System.out.println("正在准备执行");
}
@After("whenRetryMethodExecuted(maxNum)")
public void endExecution(int maxNum){
System.out.println("执行完毕");
}
@AfterReturning("whenRetryMethodExecuted(maxNum)")
public void otherTasks(int maxNum){
System.out.println("可以继续执行下一次操作");
}
@AfterThrowing("whenRetryMethodExecuted(maxNum)")
public void executionFail(int maxNum){
System.out.println("重试次数超过最大次数");
}
@Around("whenRetryMethodExecuted(maxNumt)")
public Object retryExecution(ProceedingJoinPoint joinPoint, int maxNumt) throws RuntimeException {
int maxNum = maxNumt;
Object obj = null;
while(maxNum > 0) {
try {
obj = joinPoint.proceed();
} catch (Throwable throwable) {
maxNum--;
continue;
}
break;
}
if(maxNum == 0){
throw new RuntimeException("失败次数超过重试上限");
}else{
System.out.println("执行成功");
}
return obj;
}
}
上面写了一个简单的重试功能,这个也是书中提到的一个around注解会被用到的功能。
package com.glodon.springdemo6;
import org.springframework.stereotype.Component;
import java.util.Random;
@Component
public class RetryComp{
public void retryMethod(int maxNum) throws Throwable {
Random random = new Random();
if(random.nextInt(20) < 15){
throw new Throwable();
}
}
}
测试类:注释掉还没走通的实验就先不放上来了
package com.glodon.springdemo6;
import com.glodon.springdemo6.newFeature.FeatureAdded;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) throws Throwable{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
RetryComp retryComp = context.getBean(RetryComp.class);
retryComp.retryMethod(15);
// ((FeatureAdded)retryComp).newFeature();
}
}