AspectJ用注解替换xml配置

AspectJ基于注解的使用

AspectJ简介

AspectJ是一个基于Java语言的AOP框架,一般

其主要用途:自定义开发

一般情况下spring自动生成代理,要配置aop,

首先确定目标类,aspectj 切入点表达式,需要导入jar包

       spring-framework-3.0.2.RELEASE-dependenciesorg.aspectjcom.springsource.org.aspectj.weaver1.6.8.RELEASE

除了以上这个关键包,还有spring所需的5个基础包,以及其他三个包,具体情况如下图:

在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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                              http://www.springframework.org/schema/beans/spring-beans.xsd
                              http://www.springframework.org/schema/aop 
                              http://www.springframework.org/schema/aop/spring-aop.xsd
                              http://www.springframework.org/schema/context 
                              http://www.springframework.org/schema/context/spring-context.xsd">

                    
        <!-- 1.扫描 注解类 -->
    <context:component-scan base-package="com.xk.proxy.aspectJ_zhujie"></context:component-scan>

</beans>

接着在service层用注解替换原先xml文件中的Bean

@Service("userServiceId")
public class UserServiceImpl implements UserService {
}

替换

<bean id="userServiceId" class="xxx.xxx.UserServiceImpl"></bean>

 在切面类中用注解替换相应Bean

@Component
public class MyAspect {
    }

替换

<bean id="myAspectId" class="xxx.xxx.xxx.aspectJ.MyAspect"></bean>

接着必须要进行aspectj 自动代理配置,否则即使声明了切面,也无法获取切面类中的方法

<!-- 1.扫描 注解类 -->
<context:component-scan base-package="xxx.xxx.xxx.aspectJ_zhujie"></context:component-scan>

添加注解@Aspect ,声明切面,以获取切面方法

@Component
@Aspect
public class MyAspect {
    }

注解@Aspect替换了

<aop:aspect ref="myAspectId">

<aop:aspect> 将切面类 声明“切面”,从而获得通知(方法)  ref 切面类引用

接着替换 公共切入点

<aop:pointcut expression="execution(* xxx.xxx.proxy.aspectJ.UserServiceImpl.*(..))" id="myPointCut"/>

这里涉及到了切入点表达式

execution()用于描述方法

       语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

       修饰符,一般省略

  返回值,不能省略,

  方法名,不能省略

  ‘ * ’表示任意

  (参数)

  ()      表示无参

       (..)          表示参数任意

用注解替换为

//声明公共切入点
@Pointcut("execution(* xxx.xxx.proxy.aspectJ.UserServiceImpl.*(..))")    
private void myPointCut(){
}

这里我用的是环绕通知类型,所以替换环绕

<aop:around method="myAround" pointcut-ref="myPointCut"/>
@Around(value = "myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("前");
        //手动执行目标方法
        Object obj = joinPoint.proceed();
        
        System.out.println("后");
        return obj;
    }

最后替换抛出异常

<aop:after-throwing method="myAfterThrowing" pointcut="execution(* xxx.xxx.UserServiceImpl.*(..))" throwing="e"/>
@AfterThrowing(value="execution(* xxx.xxx.UserServiceImpl.*(..))" ,throwing="e")
public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
    System.out.println("抛出异常通知 : " + e.getMessage());
  }

最终切面类:

/**
 * 切面类,可含有多个通知
 */
@Component
@Aspect
public class MyAspect {
    
    //切入点当前有效
    //@Before("execution(*xxx.xxx.UserServiceImpl.*(..))")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知 : " + joinPoint.getSignature().getName());
    }
    
    //声明公共切入点
    @Pointcut("execution(*xxx.xxx.UserServiceImpl.*(..))")
    private void myPointCut(){
    }
    
//  @AfterReturning(value="myPointCut()" ,returning="ret")
    public void myAfterReturning(JoinPoint joinPoint,Object ret){
        System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
    }
    
//  @Around(value = "myPointCut()")
    public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("前");
        //手动执行目标方法
        Object obj = joinPoint.proceed();        
        System.out.println("后");
        return obj;
    }
    
//  @AfterThrowing(value="execution(* xxx.xxx.UserServiceImpl.*(..))" ,throwing="e")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("抛出异常通知 : " + e.getMessage());
    }
    
    @After("myPointCut()")
    public void myAfter(JoinPoint joinPoint){
        System.out.println("最终通知");
    }

}

    

 

最终spring配置:

<!-- 1.扫描 注解类 -->
<context:component-scan base-package="com.xk.proxy.aspectJ_zhujie"></context:component-scan>
    
<!-- 2.确定 aop注解生效 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

aop注解总结:

  @Aspect  声明切面,修饰切面类,从而获得 通知。

  通知

       @Before 前置

       @AfterReturning 后置

       @Around 环绕

       @AfterThrowing 抛出异常

       @After 最终

切入点

       @PointCut ,修饰方法 private void xxx(){}  之后通过“方法名”获得切入点引用

原文地址:https://www.cnblogs.com/xk920/p/9795589.html