zoukankan      html  css  js  c++  java
  • 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(){}  之后通过“方法名”获得切入点引用

  • 相关阅读:
    【openwrt】——lua字符串操作
    Andriod绘图的基础知识
    protect,public,private 的区别
    fatjar 将项目使用的第三方jar包打包(亲测可用)
    TPshop学习(8)微信支付
    HTTP和HTTPS有什么区别? 什么是SSL证书?使用ssl证书优势?
    LNMP安装Let’s Encrypt 免费SSL证书方法:自动安装与手动配置Nginx
    腾讯云中ssL证书的配置安装
    微信小程序:微信登陆(ThinkPHP作后台)
    转载VC6LineNumberAddin 规格严格
  • 原文地址:https://www.cnblogs.com/xk920/p/9795589.html
Copyright © 2011-2022 走看看