Spring AOP 使用

在Spring项目中, 使用Spring AOP只需要3步.

1. 增加两个依赖
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.6</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>
2. 配置类上加EnableAspectJAutoProxy注解

配置类是有Configuration注解的类.

EnableAspectJAutoProxy注解用于开启aop功能, 和配置使用哪种代理, 默认是jdk的基于接口的代理(也可以用cglib的基于类的代理).

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
    
}
3. 实现
3.1. 注解方式实现
  1. 在bean上加上Aspect注解, 表示这个bean是切面.
  2. 定义个通知方法, 通知器方法的参数必须是连接点, 方法上需要配置通知类型和切点的表达式.
package com.leolab.spring.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {
    
    // 前置通知
    @Before("execution(* com.leolab.spring.demo.*ServiceImpl.*(..))")
    public void BeforePrintLog(JoinPoint joinPoint){
        System.out.println("BeforePrintLog...");
    }

    // 环绕通知
    @Around("execution(* com.leolab.spring.demo.*ServiceImpl.*(..))")
    public Object AroundPrintLog(JoinPoint joinPoint) throws Throwable {
        System.out.println("AroundPrintLog 1...");
        ProceedingJoinPoint pjp = (ProceedingJoinPoint) joinPoint;
        Object proceed = pjp.proceed();
        System.out.println("AroundPrintLog 2...");
        return proceed;
    }
}
3.2. 代码方式实现

要继承AbstractPointcutAdvisor类, 实现通知器, 通知, 切点, 类过滤器, 方法匹配器

package com.leolab.spring.demo.aop;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class MyAdvisor extends AbstractPointcutAdvisor {

    private Pointcut pc = new MyPointcut();

    @Override
    public Pointcut getPointcut() {
        return pc;
    }

    @Override
    public Advice getAdvice() {
        return new MethodInterceptor(){
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                
                // 前
                System.out.println("MyAdvisor 11 ...");
                
                // 继续调用拦截器或者目标方法
                Object proceed = invocation.proceed();

                // 后
                System.out.println("MyAdvisor 22 ...");
                return proceed;
            }
        };
    }
}

class MyPointcut implements Pointcut{

    private ClassFilter classFilter = new MyClassFilter();

    private MethodMatcher methodMatcher = new MyMethodMatcher();

    @Override
    public ClassFilter getClassFilter() {
        return classFilter;
    }

    @Override
    public MethodMatcher getMethodMatcher() {
        return methodMatcher;
    }
}

class MyMethodMatcher implements MethodMatcher{

    // 匹配List结尾的方法
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        return method.getName().endsWith("List");
    }

    @Override
    public boolean isRuntime() {
        return false;
    }

    @Override
    public boolean matches(Method method, Class<?> targetClass, Object... args) {
        throw new UnsupportedOperationException();
    }
}

class MyClassFilter implements ClassFilter{

    // 匹配ServiceImpl结尾的方法
    @Override
    public boolean matches(Class<?> clazz) {
        return clazz.getName().endsWith("ServiceImpl");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值