Maven

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.4</version>
        </dependency>

一般都在spring 框架中使用,即
org.springframework.web 之类的依赖最好也存在

如果为 一般的spring 环境,且存在 applicationContext.xml

存在的情况下需要开启该xml 中的配置如下:
在这里插入图片描述

<aop:aspectj-autoproxy proxy-target-class="true" />
    <aop:config expose-proxy="true">
        <aop:pointcut id="allManagerMethod" expression="(execution(* com.test.demo.service..*.*(..))
        or execution(* com.test.demo.test.manager..*.*(..)))
        and not execution(* com.test.demo.ignore.service*(..)) and not execution(* com.test.demo.ignore.test.*(..))
        "/>
        <aop:advisor advice-ref="tAdvice" pointcut-ref="allManagerMethod"/>
    </aop:config>
    
<!-- 单数据源事务 -->
<tx:advice id="tAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="start*" propagation="REQUIRED" rollback-for="com.test.demo.TestException"/>
            <tx:method name="execute*" propagation="REQUIRED" rollback-for="com.test.demo.TestException"/>
            ........
            </tx:attributes>
    </tx:advice>

实际在类中定义的使用案例(一般方法和携带自定义注解的方法增强)

@Aspect
@Component
public class MyAspect {

//    可以注入一般的Service
//    @Resource(name = "userService")
//    private UserService userService;

     // 包路径下的所有
     @Pointcut("execution(* com.test.demo.test..*(..))")
     public void testPackage() {
        // 定义切入点
     }
     
     // 某一路径下的类的 某一方法,这里 Taskhandler 为某一接口   taskCreate为指定的方法
     @Pointcut("execution(* com.test.demo.Taskhandler+.taskCreate (..))")
     public void taskCreate() {
        // 定义切入点
     }

     // 某一个注解
     @Pointcut("@annotation(com.test.demo.test.MyAnnotation)")
     public void MyAnnotation() {
        // 定义切入点
     }

    // 循环增强 前后都增强  value 即上方定义的Pointcut
    @Around(value = "MyAnnotation()")
    public Object annotationTest(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        // 获取请求中携带的参数
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                
        String idStr = request.getParameter("id").toString();
        String name = request.getParameter("name").toString();
        // 或 request.getAttribute("") 获取参数
        //  .................... 自己的其他操作
        // 执行完成后放行 正常进入原有方法
        return joinPoint.proceed(args);
    }
    
    // 前增强  在进入指定方法前执行的代码
    @Before(value = "testPackage()")
    public void testMethod1() {
        // ....... 其他任何操作 这里可以与 ThreadLocal 连用 在ThreadLocal 中存储或者获取,
        // 或者修改一些数据 去做部分处理 但不要忘记 threadLocal 的 remove
    }

    // 后增强  在指定方法结束后执行代码 使用 || 可以标识多个 pointCut 都要执行
    @After(value = "taskCreate() || testPackage() || MyAnnotation()")
    public void testMethod1() {
        // ....... 其他任何操作 这里可以与 ThreadLocal 连用 在ThreadLocal 中存储或者获取,
        // 或者修改一些数据 去做部分处理 但不要忘记 threadLocal 的 remove
    }

}

从 joinPoint 获取当前方法对象 Method

入参类型 ProceedingJoinPoint joinPoint

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        // 获取到 方法上的注解对象后,如果给注解定义了一些属性,那么此时也可以通过该注解的对象获取到

其他注解

@AfterReturning
在方法执行完成后的增强部分

@AfterThrowing
在异常抛出后的增强部分

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐