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
