Aop简单搭建

第一步:在springMvc的xml文件里配置

    <context:component-scan base-package="com.aspectJ"/>
    <aop:aspectj-autoproxy/>

第二步:编写Aop配置的java类

package com.aspectJ;

/**
 * Created by tang on 2018/4/25.
 */

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 注解声明一个aspectj,比较测试5种通知
 */

/**
 * 把这个类声明为一个切面:
 * 1. 使用注解“@Component”把该类放入到IOC容器中
 * 2. 使用注解“@Aspect”把该类声明为一个切面
 * <p>
 * 设置切面的优先级:
 * 3. 使用注解“@Order(number)”指定前面的优先级,值越小,优先级越高
 */
//@Order(1)
@Aspect
@Component
public class AspectJAdvice {

    /**
     * 表达式例子如下:
     *   任意公共方法的执行:
     *     execution(public * *(..))
     *   任何一个以“set”开始的方法的执行:
     *     execution(* set*(..))
     *   AccountService 接口的任意方法的执行:
     *     execution(* com.xyz.service.AccountService.*(..))
     *   定义在service包里的任意方法的执行:
     *     execution(* com.xyz.service.*.*(..))
     *   定义在service包和所有子包里的任意类的任意方法的执行:
     *     execution(* com.xyz.service..*.*(..))
     *   定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
     *     execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
     *   在多个表达式之间使用 ||,or表示 或,使用 &&,and表示 与,!表示 非.例如:
     * <aop:config>
     *     <aop:pointcut id="pointcut" expression="(execution(* com.ccboy.dao..*.find*(..))) or (execution(* com.ccboy.dao..*.query*(..)))"/>
     *     <aop:advisor advice-ref="jdbcInterceptor" pointcut-ref="pointcut" />
     *   </aop:config>
     */
    @Pointcut("execution(* com.service.ITradeCompanyService.*(..))")//调用ITradeCompanyService里面的任何方法都算是这个切入点
    public void pointCutMethod() {
//        System.out.println("我是pointCutMethod===================================================");
//        System.out.println("我是切入点,即需要增强的方法");
    }

    /**
     * 可以在通知方法中声明一个类型为 JoinPoint 的参数。然后就能访问链接细节。如方法名称和参数值
     * 声明该方法是一个前置通知:在目标方法开始之前执行
     *
     * @param joinPoint
     */
    @Before("execution(* com.controllers.*.*(..))")//调用controllers包里面的任何controller类里面的方法都会触发此方法
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("我是前置通知的方法:");
        //获取方法名称
        String methodName = joinPoint.getSignature().getName();
        //获取参数值
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println("Taget method: " + methodName);
        System.out.println("Taget method args: " + args);
    }

    /**
     * 如果只想在连接点返回的时候记录日志,应使用返回通知代替后置通知。
     * 在返回通知中,只要将 returning 属性添加到 @AfterReturning 注解中,就可以访问连接点的返回值
     * 声明该方法是一个返回通知:在目标方法正常结束之后返回(目标方法执行出现异常时不再执行)
     * 返回通知可以访问目标方法的执行结果
     *
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "execution(* com.aspectJ.cutPoint.*.*(..))", returning = "result")
    public void afterQueryReturning(JoinPoint joinPoint, Object result) {
        System.out.println("我是返回通知的方法:");
        String methodName = joinPoint.getSignature().getName();
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println("Taget method: " + methodName);
        System.out.println("Taget method args: " + args);
        System.out.println("Taget method execute result: " + result);
    }


    /**
     * 声明该方法是一个异常通知:在目标方法出现异常时执行此方法
     * 异常通知可以访问目标方法中的异常对象,且可以指定在出现特定异常时再执行通知代码
     */
    @AfterThrowing(value = "pointCutMethod()", throwing = "e")
    public void afterAllThrowing(JoinPoint joinPoint, Exception e) {
        System.out.println("我是异常通知的方法:");
        System.out.println("方法执行时抛出的异常" + e);
    }

    /**
     * 声明该方法是一个后置通知:在目标方法开始之后执行(即使目标方法执行出现异常也会执行)
     * 后置通知中不能访问目标方法的执行结果
     */
    @After("pointCutMethod()")
    public void doAfter() {
        System.out.println("我是后置通知的方法:");
    }

    /**
     * 环绕通知需要携带ProceedingJoinPoint类型的参数
     * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法
     * 且环绕通知必须有返回值,返回值即为目标方法的返回值
     */
    @Around("pointCutMethod()")
    public Object around(ProceedingJoinPoint pj) {
        String methodName = pj.getSignature().getName();
        Object object = null;

        try {
            System.out.println(" 我是环绕方法执行之前的输出,我比前置方法执行的还早");
            //执行目标方法
            object = pj.proceed();
            System.out.println("我是环绕方法我执行了");
        } catch (Throwable e) {
            //异常通知
            System.out.println("The method: " + methodName + "异常通知: " + e.getMessage());
        }


        return object;
    }


}

第三步:编写测试类

package com.aspectJ;

import com.aspectJ.cutPoint.MyCutPoint;
import com.dto.TradeCompany;
import com.service.ITradeCompanyService;
import com.service.impl.TradeCompanyServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.Schedules;

/**
 * Created by tang on 2018/4/25.
 */
public class TestAspectAdvice {

    @Test
    public void testAnnotationBeforeAdvice() {
        System.out.println("======================================");
        ApplicationContext context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
        ITradeCompanyService myCutPoint = (ITradeCompanyService) context.getBean("tradeCompanyServiceImpl");
        myCutPoint.selectCompany(new TradeCompany(),1,10);
        System.out.println("======================================");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值