Spring AOP切面基于注解基础学习

首先我们先创建一个接口类,写一个简单易懂的例子,比如,实现加减乘除的接口,然后我们通过该接口来实现基于注解的切面实现。

package com.text2;

public interface C1 {

    public int jia(int a, int b);
    public int jian(int a, int b);
    public int chen(int a, int b);
    public int chu(int a, int b);

}

下面是接口的实现类:
package com.text2;

import org.springframework.stereotype.Component;

@Component(“C1”)/声明改类为Spring管理的/
public class C1Impl implements C1 {
public C1Impl() {
System.out.println(“C1Impl构造器”);
}

public int jia(int a, int b) {
    return a+b;
}

public int jian(int a, int b) {
    return a-b;
}

public int chen(int a, int b) {
    return a*b;
}

public int chu(int a, int b) {
    return a/b;
}

}

下面我们实现切面:

package com.text2;

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;
import java.util.List;

/**
 * 将该类声明为一个切面:需要把该类放入到IOC容器中,再声明为一个切面 @aspect
 * 使用Order声明切面的优先级,值越小优先级越高
 */
@Order(1)
@Aspect/*声明为切面*/
@Component/*声明为spring管理的组件*/
public class C2 {
    /**
     * 定义一个方法,用于声明切入点表达式,该方法中不需要添入其他的代码
     * 使用@Pointcut来声明切入点表达式
     * 后面的其他通知直接使用方法名来引入切入点表达式
     */
    @Pointcut("execution(* com.text2.C1.*(..))")
    public void declareJointPointExpression(){}

    /**
     * 声明该方法是一个前置通知,
     * 在目标方法开始之前执行
     * @param joinPoint
     */
    @Before("declareJointPointExpression()")
    public void beforeMethod(JoinPoint joinPoint){
        //得到方法的名字
        String name = joinPoint.getSignature().getName();
        //得到方法的参数
        List<Object> list = Arrays.asList(joinPoint.getArgs());
        System.out.println("The beforeMethod :"+name+list);
    }

    /**
     * 声明该方法是一个后置通知,在连接点返回结果或者抛出异常的时候,
     * 下面的后置通知记录了方法的终止,
     * 在后置通知中还不能访问目标方法执行的结果
     * @param joinPoint
     */
    @After("declareJointPointExpression()")
    public void afterMethod(JoinPoint joinPoint){
        //得到方法的名字
        String name = joinPoint.getSignature().getName();
        //得到方法的参数
        List<Object> list = Arrays.asList(joinPoint.getArgs());
        System.out.println("The afterMethod :"+name+list);
    }

    /**
     * 返回通知,返回通知是可以访问到方法的返回值的
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "declareJointPointExpression()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("The afterReturning "+name+" ends with "+ result.toString());
    }



    /**
     * 异常通知,在目标方法出现异常时会执行的代码,
     * 可以访问到异常对象;且可以指定在出现特定异常时在执行通知代码
     * @param joinPoint
     * @param ex
     */
    @AfterThrowing(value = "declareJointPointExpression()",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Exception ex){
        String name = joinPoint.getSignature().getName();
        System.out.println("The afterThrowing "+name+" ends with "+ ex.toString());
    }

    /**
     * 环绕通知:跟动态代理一样,需要携带ProceedingJoinPoint类型的参数
     * 环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标
     * 且必须有返回值,返回值为目标方法的返回值
     * @param proceedingJoinPoint
     * @return
     */
    @Around(value = "declareJointPointExpression()")
    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
        Object o = null;
        String methodName = proceedingJoinPoint.getSignature().getName();
        //执行目标方法
        try {
            //前置通知
            System.out.println("The aroundMethod "+methodName+" begins with "+ Arrays.asList(proceedingJoinPoint.getArgs()));
            o = proceedingJoinPoint.proceed();
            //返回通知
            System.out.println("The aroundMethod "+ methodName +" ends with "+ o);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            //异常通知
            System.out.println("The aroundMethod "+ methodName +" occurs exception: "+ throwable);
        }
        //后置通知
        System.out.println("The aroundMethod "+ methodName+" ends");
        return o;
    }
}

测试类:

package com.text2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import static org.junit.Assert.*;

public class TestC {
    @org.junit.Test
    public void b1() throws Exception {
        /*创建Spring的IOC容器*/
        ApplicationContext ctx = new ClassPathXmlApplicationContext("text2.xml");
        /*从IOC中获取bean的实例*/
        C1 c1 = (C1) ctx.getBean("C1");
        int result = c1.chu(10,2);
        System.out.println("值:"+result);

    }

}

XML配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!--可以设置包含与不包含那些包下的与类,接口-->
        <context:component-scan base-package="com.text2"></context:component-scan>
        <!--使AspjectJ注解起作用:自动为匹配的对象生成代理对象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


</beans>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走到无路可退

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值