Spring学习笔记6——@AspectJ编写切面

 首先看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();
    }
}

 

你可能感兴趣的:(Spring,java)