JAVA切面编程简单实现

文章展示了如何在Java中使用SpringAOP进行方法监控,定义了一个枚举NodeEnum作为节点标识,创建了一个@Monitor注解来标记需要监控的方法。MonitorHandlerAspect类作为切面处理类,处理被@Monitor注解的方法,记录正常或异常的日志。InteTestImpl类实现了InteTest接口并使用注解定义了需要监控的方法。
摘要由CSDN通过智能技术生成

定义节点

public enum NodeEnum {

    A("A"),
    B("B"),
    C("C"),
    D("D"),
    E("E"),
    ;

    NodeEnum(String desc) {
        this.desc = desc;
    }

    private String desc;

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

}

定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Monitor {

    NodeEnum node();

}

定义增强处理类

@Aspect
@Component
@Order(0)
class MonitorHandlerAspect {

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.cp.test.aop.Monitor)")
    public void HandlerPointcut() {
    }

    /**
     * 增强处理主流程
     */
    @Around("HandlerPointcut()")
    public <T> T handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {

        // 获取方法名
        String methodName = pjp.getSignature().getName();

        // 获取方法所属类
        Class<?> classTarget = pjp.getTarget().getClass();

        // 获取方法参数类型
        Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();

        // 获取方法
        Method objMethod = classTarget.getMethod(methodName, par);

        // 获取方法上的注解
        Monitor monitor = objMethod.getAnnotation(Monitor.class);

        try {
            // 手动控制该方法执行
            T proceed = (T) pjp.proceed();

            // 日志正常记录
            this.record(monitor);
            return proceed;
        } catch (Throwable e) {
            // 日志异常记录
            this.recordException(monitor, e);
            throw e;
        }
    }

    /**
     * @desc: 正常日志记录
     */
    private void record(Monitor monitor) {
        if (NodeEnum.A.equals(monitor.node())) {
            System.out.println("我是正常日志切面处理,监控到被标记A节点的方法执行了,正在记录日志中。。。");
        }
    }

    /**
     * @desc: 异常日志记录
     */
    private void recordException(Monitor monitor, Throwable e) {
        if (NodeEnum.A.equals(monitor.node())) {
            System.out.println("我是异常日志切面处理,监控到被标记A节点的方法执行时异常了,异常信息是" + e);
        }
    }
}

定义测试接口

public interface InteTest {

    void test();

    void proxyTest();
}

实现测试接口

@Service
public  class InteTestImpl implements InteTest {

    @Override
    @Monitor(node = NodeEnum.A)
    public void test() {

        // 自代理调用
        InteTest proxy = (InteTest) AopContext.currentProxy();
        proxy.proxyTest();

//        this.proxyTest();

        // int a = 4 / 0;
        System.out.println("我是方法A,我正在执行中。。。");
    }

    @Override
    @Monitor(node = NodeEnum.B)
    public void proxyTest() {
        System.out.println("我是方法B,我正在执行中。。。");
    }
}

定义测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class MonTest {

    @Resource
    private InteTest inteTest;

    @Test
    public void test() {
        inteTest.test();
    }
}

正常监控日志

image.png

异常监控日志

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值