zoukankan      html  css  js  c++  java
  • 17Spring_AOP编程(AspectJ)_AspectJ的注解编程

    前面的各种Aop编程,都是基于XML的,这篇文章讲的是把XML方式改为注解方式来做。

    Spring注解开发和xml开发所需要的包是一样的,所以只要把xml开发方式的包复制到以注解为开发方式的包的项目下就可以了。

    第一步:导入相应的jar包

    第二步:需要在applicationContext.xml中引入aop的名称空间

    开启注解自动代理:

    <!-- 自动注解 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 

    第三步:AOP编程:

    第(一)步.目标对象:

    //编写目标类(真正被代理的)
    public class UserDaoImpl implements UserDao {
    
        
    
        public int delete() {
            System.out.println("删除了");
               return 1;
        
        }
    
    }

    第(二)步:编写切面类和Advice方法

    //这个注解表明这个类就是切面类,在这个类里面可以写Advice(通知)方法。
    @Aspect
    public class Myspect { //我们配置一个前置方法的Advice方法,这是一个Advice方法,当然要配置切点了。配了切点就表示在这个切点执行这个Advice方法。 @Before("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))") public void before1(JoinPoint joinPoint) { System.out.print("this is 前置方法"); } //后置通知,这是一个Advice方法,当然要配置切点了。配了切点就表示在这个切点执行这个Advice方法。 @AfterReturning(value="execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))",returning="returnVal") public void afterReturning(JoinPoint joinPoint,Object returnVal) { System.out.println("this is afterReturning 方法"); System.out.println(returnVal); } }

    第四步:在Spring配置文件中配置目标Bean和切面Bean

    <!-- xml配置目标bean和切面bean -->
    <bean id="UserDao" class="com.guigu.shen.anotion.UserDaoImpl"></bean>
    <bean id="Myspect" class="com.guigu.shen.anotion.Myspect"></bean>

     接下来给出Aspect5种通知的注解形式的具体实例

    前置通知@Before

    //前置通知
    @Before("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))") public void before1(JoinPoint joinPoint) { System.out.print("this is 前置方法"); }

    后置通知:

    //后置通知
    @AfterReturning(value="execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))",returning="returnVal")
    public void afterReturning(JoinPoint joinPoint,Object returnVal)
    {
    System.out.println("this is afterReturning 方法");
    System.out.println(returnVal);
        
    }

    环绕通知:

    //环绕通知,在方法的前后执行,在工作中可以计算方法执行的时间,性能的监控,权限的设置,缓存的实行等
    @Around("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
    {
        long begintime=System.currentTimeMillis();
        Object result=proceedingJoinPoint.proceed();
        long endtime=System.currentTimeMillis();
        System.out.println("方法执行了"+(endtime-begintime)+"时间");
        return result;
    
    }

     异常通知:指的是当发生一些异常时会输出异常信息(如果方法没有异常的话,这个通知不会被执行的,比如如果.UserDaoImpl中的delete()方法会产生一个异常,

    那么这个切点通知方法会执行,如果UserDaoImpl中的delete()方法没哟异常就不会执行这个方法)

    @AfterThrowing(value="execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))",throwing="e")
    public void afterThrowing(JoinPoint joinPoint,Exception e)
    {
        System.out.print(joinPoint.toLongString()+"方法发生了异常"+e.getMessage());
    }

    情形一:

    被代理类的方法:

    //编写目标类(真正被代理的)
    public class UserDaoImpl implements UserDao {
    
        
    
        public int delete() {
            System.out.println("删除了");
            //int a=1/0;
               return 1;
        
        }
    
    }

    测试方法:

    @Test
        public void deletetest()
        {
            userDao.delete();
        }

    结果:不会输出异常的信息。

    情形二:

    被代理类的方法:

    //编写目标类(真正被代理的)
    public class UserDaoImpl implements UserDao {
    
        
    
        public int delete() {
            System.out.println("删除了");
              int a=1/0;
               return 1;
        
        }
    
    }

    测试方法:

    @Test
        public void deletetest()
        {
            userDao.delete();
        }

    结果:execution(public abstract int com.guigu.shen.anotion.UserDao.delete())方法发生了异常/ by zero18:36:25,064  INFO GenericApplicationContext:1042 - Closing org.springframework.context.support.GenericApplicationContext@24f9fdc: startup date [Mon Aug 01 18:36:07 CST 2016]; root of context hierarchy

    最终通知:

    @After("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))")
    public void after()
    {
        System.out.print("最终通知,释放资源");
    
    }

    结果:

    this is 前置方法

    删除了
    方法执行了0时间
    最终通知,释放资源

    this is afterReturning 方法

    下面给出整个案例的结构图以及代码

    Myspect.java是切面类
    //定义一个切面类。以及Advice方法
    //这个注解表明这是切面类
    @Aspect
    public class Myspect {
        //我们配置一个前置方法的Advice方法,这是一个Advice方法,当然要配置切点了
    @Before("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))")
    public void before1(JoinPoint joinPoint)
    {
        System.out.print("this is 前置方法");
    }
    //后置通知
    @AfterReturning(value="execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))",returning="returnVal")
    public void afterReturning(JoinPoint joinPoint,Object returnVal)
    {
    System.out.println("this is afterReturning 方法");
    System.out.println(returnVal);
        
    }
    
    //环绕通知,在方法的前后执行,在工作中可以计算方法执行的时间,性能的监控,权限的设置,缓存的实行等
    @Around("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
    {
        long begintime=System.currentTimeMillis();
        Object result=proceedingJoinPoint.proceed();
        long endtime=System.currentTimeMillis();
        System.out.println("方法执行了"+(endtime-begintime)+"时间");
        return result;
    
    }
    @AfterThrowing(value="execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))",throwing="e")
    public void afterThrowing(JoinPoint joinPoint,Exception e)
    {
        System.out.print(joinPoint.toLongString()+"方法发生了异常"+e.getMessage());
    }
    @After("execution(* com.guigu.shen.anotion.UserDaoImpl.*(..))")
    public void after()
    {
        System.out.print("最终通知,释放资源");
    
    }
    
    }

    UserDao接口类:

    public interface UserDao {
    public int delete();
    }

    UserDao接口的实现类:

    //编写目标类(真正被代理的)
    public class UserDaoImpl implements UserDao {
    
        
    
        public int delete() {
            System.out.println("删除了");
            //int a=1/0;
               return 1;
        
        }
    
    }

    Junit测试类:

    //JUnit与Spring的整合 (用注解)
    @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class TestMyspect { @Autowired private UserDao userDao; @Test public void deletetest() { userDao.delete(); } public void aroundTest() { userDao.delete(); } }

     ApplicationContext.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:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                               http://www.springframework.org/schema/aop 
                               http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                               http://www.springframework.org/schema/context 
                               http://www.springframework.org/schema/context/spring-context-2.5.xsd
                               http://www.springframework.org/schema/tx 
                               http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
    <!-- AspectJ AOP -->
    
    
    
    <!-- 自动注解 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 
    <!-- xml配置目标bean和切面bean -->
    <bean id="UserDao" class="com.guigu.shen.anotion.UserDaoImpl"></bean>
    <bean id="Myspect" class="com.guigu.shen.anotion.Myspect"></bean>
    
    
    
    <!--
    流程解释:
     xml配置目标bean和切面bean,这样一来bean就会被加载,对象就创建好了,然后我们在之前不是配置了一个<aop:aspectj-autoproxy></aop:aspectj-autoproxy>了吗
     这样就能给我们创建的UserDao和Myspect对象做代理了
     -->
    
    </beans>
  • 相关阅读:
    技术期刊 · 五等分の花嫁 | Vue 3.2 正式发布!;大型项目管理策略;开源社区运营就像种菜;阮一峰的 fetch 教程;Webpack5 学习的平凡之路
    最近很火的低代码到底是什么?
    测试开发之前端篇-Web前端简介
    痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道
    痞子衡嵌入式:其实i.MXRT下改造FlexSPI driver同样支持AHB方式去写入NOR Flash
    《痞子衡嵌入式半月刊》 第 38 期
    [Vue深入组件]:native事件修饰符以及拓展之自定义组件的事件监听目标DOM元素自定义
    [Vue深入组件]:v-model语法糖与自定义v-model
    [Vue深入组件]:禁用 Attribute 继承
    @from [GITHUB] : Learn regex the easy way
  • 原文地址:https://www.cnblogs.com/shenxiaoquan/p/5726953.html
Copyright © 2011-2022 走看看