zoukankan      html  css  js  c++  java
  • SpringAOP使用注解实现5种通知类型

    spring aop的5种通知类型都有

    Before前置通知

    AfterReturning后置通知

    Around环绕通知

    AfterThrowing异常通知

    After最终通知

    首先创建接口和实现类 先测试后置通知

    package com.aaa.spring.dao;
    
    
    
    public interface UserService {
    
        public void insertUser();
    
        public void updateUser();
    
        public void deleteUser();
    
        public void find();
    }
    package com.aaa.spring.dao.umpl;
    
    import com.aaa.spring.dao.UserService;
    import com.aaa.spring.exception.MyException;
    import org.springframework.stereotype.Component;
    
    @Component(创建userServiceImpl bean)
    public class UserServiceImpl implements UserService {
        @Override
        public void insertUser() {
            System.out.println("添加用户");
        }
    
        @Override
        public void updateUser() {
            System.out.println("修改用户");
        }
    
        @Override
        public void deleteUser() {
            System.out.println("删除用户");
        }
    
        @Override
        public void find() {
            System.out.println("查询用户");
        }
    }

    创建要在执行的方法前后的类

    package com.aaa.spring.advice;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    @Component(获取bean对象)
    @Aspect(面向切面)
    public class LogAdvice {
        @AfterReturning("execution(void *User(..))")(后置通知(切入点))
        public void log(JoinPoint jp){  (JoinPoint 连接点参数)
            String name=jp.getSignature().getName();(获取拦截的方法名)
            System.out.println(name+"执行之后记录成功");
        }
    }

    创建ApplicationContext文件

    <?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.aaa.spring"></context:component-scan>(扫描创建bean的包就是加@Component的类的所有包 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>(声明以注解的方式配置spring aop) </beans>

    创建测试类

    package com.aaa.spring.text;
    
    import com.aaa.spring.dao.UserService;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    
    public class Text {
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationcontext.xml");(获取主配置文件)
            UserService bean = (UserService)context.getBean("userServiceImpl");(获取实现类对象)
            bean.deleteUser();
            System.out.println("*****************************");
            bean.find();
            System.out.println("*****************************");
            bean.insertUser();
            System.out.println("*****************************");
            bean.updateUser();
    
        }
    }

    测试结果

    五月 20, 2019 9:01:24 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:01:24 CST 2019]; root of context hierarchy
    五月 20, 2019 9:01:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
    删除用户
    deleteUser执行之后记录成功
    *****************************
    查询用户
    *****************************
    添加用户
    insertUser执行之后记录成功
    *****************************
    修改用户
    updateUser执行之后记录成功
    
    Process finished with exit code 0

    前置通知

    只需要在LogAdvice 类里边再加方法

    package com.aaa.spring.advice;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    @Component
    @Aspect
    public class LogAdvice {
        @AfterReturning("execution(void *User(..))")
        public void log(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之后记录成功");
        }
        @Before("execution(void *User(..))")
        public void befor(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之前记录成功");
        }
    }

    测试结果

    五月 20, 2019 9:08:07 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:08:07 CST 2019]; root of context hierarchy
    五月 20, 2019 9:08:08 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
    deleteUser执行之前记录成功
    删除用户
    deleteUser执行之后记录成功
    *****************************
    查询用户
    *****************************
    insertUser执行之前记录成功
    添加用户
    insertUser执行之后记录成功
    *****************************
    updateUser执行之前记录成功
    修改用户
    updateUser执行之后记录成功
    
    Process finished with exit code 0

    环绕通知

    只需要在LogAdvice 类里边再加方法

    package com.aaa.spring.advice;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    @Component
    @Aspect
    public class LogAdvice {
        @AfterReturning("execution(void *User(..))")
        public void log(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之后记录成功");
        }
        @Before("execution(void *User(..))")
        public void befor(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之前记录成功");
        }
        @Around("execution(void *User(..))")
        public  void around(ProceedingJoinPoint pjp){
            String name=pjp.getSignature().getName();
            System.out.println(name+"环绕执行前");
            try {
                pjp.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            System.out.println(name+"环绕后执行");
        }
    
    }

    测试结果

    五月 20, 2019 9:10:12 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:10:12 CST 2019]; root of context hierarchy
    五月 20, 2019 9:10:12 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
    deleteUser环绕执行前
    deleteUser执行之前记录成功
    删除用户
    deleteUser环绕后执行
    deleteUser执行之后记录成功
    *****************************
    查询用户
    *****************************
    insertUser环绕执行前
    insertUser执行之前记录成功
    添加用户
    insertUser环绕后执行
    insertUser执行之后记录成功
    *****************************
    updateUser环绕执行前
    updateUser执行之前记录成功
    修改用户
    updateUser环绕后执行
    updateUser执行之后记录成功
    
    Process finished with exit code 0

    最终通知

    只需要在LogAdvice 类里边再加方法

    package com.aaa.spring.advice;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    @Component
    @Aspect
    public class LogAdvice {
        @AfterReturning("execution(void *User(..))")
        public void log(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之后记录成功");
        }
        @Before("execution(void *User(..))")
        public void befor(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之前记录成功");
        }
        @Around("execution(void *User(..))")
        public  void around(ProceedingJoinPoint pjp){
            String name=pjp.getSignature().getName();
            System.out.println(name+"环绕执行前");
            try {
                pjp.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            System.out.println(name+"环绕后执行");
        }
        @After("execution(void *User(..))")
        public  void after(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"最终执行记录成功");
        }
    
    }

    测试结果

    五月 20, 2019 9:12:00 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:12:00 CST 2019]; root of context hierarchy
    五月 20, 2019 9:12:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
    deleteUser环绕执行前
    deleteUser执行之前记录成功
    删除用户
    deleteUser环绕后执行
    deleteUser最终执行记录成功
    deleteUser执行之后记录成功
    *****************************
    查询用户
    *****************************
    insertUser环绕执行前
    insertUser执行之前记录成功
    添加用户
    insertUser环绕后执行
    insertUser最终执行记录成功
    insertUser执行之后记录成功
    *****************************
    updateUser环绕执行前
    updateUser执行之前记录成功
    修改用户
    updateUser环绕后执行
    updateUser最终执行记录成功
    updateUser执行之后记录成功
    
    Process finished with exit code 0

    异常通知,这里我们自定义一个异常

    先创建一个异常类继承RuntimeException程序异常

    package com.aaa.spring.exception;
    
    public class MyException extends  RuntimeException{
        public  MyException(String yc){
            super(yc);
        }
    }

    然后在LogAdvice  类里添加方法这里为了方便测试把上面的都加上了注释

    package com.aaa.spring.advice;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    @Component
    @Aspect
    public class LogAdvice {
       /* @AfterReturning("execution(void *User(..))")
        public void log(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之后记录成功");
        }
        @Before("execution(void *User(..))")
        public void befor(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"执行之前记录成功");
        }
        @Around("execution(void *User(..))")
        public  void around(ProceedingJoinPoint pjp){
            String name=pjp.getSignature().getName();
            System.out.println(name+"环绕执行前");
            try {
                pjp.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            System.out.println(name+"环绕后执行");
        }
        @After("execution(void *User(..))")
        public  void after(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println(name+"最终执行记录成功");
        }*/
        @AfterThrowing(pointcut = "execution(void *User(..))")
        public  void excaption(JoinPoint jp){
            String name=jp.getSignature().getName();
            System.out.println("执行"+name+"时发生异常");
        }
    }

    然后在实现类里抛出异常

    package com.aaa.spring.dao.umpl;
    
    import com.aaa.spring.dao.UserService;
    import com.aaa.spring.exception.MyException;
    import org.springframework.stereotype.Component;
    
    @Component
    public class UserServiceImpl implements UserService {
        @Override
        public void insertUser() {
           if(true){
                throw new MyException("自定义异常");
            }
            System.out.println("添加用户");
        }
    
        @Override
        public void updateUser() {
            System.out.println("修改用户");
        }
    
        @Override
        public void deleteUser() {
            System.out.println("删除用户");
        }
    
        @Override
        public void find() {
            System.out.println("查询用户");
        }
    }

    测试结果

    五月 20, 2019 9:18:57 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:18:57 CST 2019]; root of context hierarchy
    五月 20, 2019 9:18:57 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
    删除用户
    *****************************
    查询用户
    *****************************
    执行insertUser时发生异常
    Exception in thread "main" com.aaa.spring.exception.MyException: 自定义异常
        at com.aaa.spring.dao.umpl.UserServiceImpl.insertUser(UserServiceImpl.java:12)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy7.insertUser(Unknown Source)
        at com.aaa.spring.text.Text.main(Text.java:17)
    
    Process finished with exit code 1
  • 相关阅读:
    NET 获取实例所表示的日期是星期几
    NET npoi 保存文件
    快速排序
    JAVA poi 合并单元格
    JAVA poi 帮助类
    JAVA 字符串编码转换
    NET npoi 合并单元值处理
    NET npoi帮助类
    Task的暂停,继续,取消
    .net ref与out之间区别
  • 原文地址:https://www.cnblogs.com/fengxiangyu/p/10896547.html
Copyright © 2011-2022 走看看