最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

聊聊注解@Aspect的AOP實現(xiàn)操作

 更新時間:2021年01月20日 14:43:41   作者:qgfjeahn  
這篇文章主要介紹了聊聊注解@Aspect的AOP實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

Spring只支持XML方式而沒有實現(xiàn)注解的方式(也叫AspectJ方式)的AOP,所以要使用@Aspect注解,只能引入AspectJ相關(guān)的 jar 包 aopalliance-1.0.jar 和 aspectjweaver.jar,這個坑把我給坑慘了。

使用步驟如下:

1、引入相關(guān)jar包

2、Spring的配置文件 applicationContext.xml 中引入context、aop對應(yīng)的命名空間;配置自動掃描的包,同時使切面類中相關(guān)方法中的注解生效,需自動地為匹配到的方法所在的類生成代理對象。

<?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-4.0.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 <!-- 配置自動掃描的包 -->
 <context:component-scan base-package="com.qcc.beans.aop"></context:component-scan>
 <!-- 自動為切面方法中匹配的方法所在的類生成代理對象。 -->
 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

3、創(chuàng)建簡單計算器的接口ArithmeticCalculator.java及實現(xiàn)類ArithmeticCalculatorImpl.java

package com.qcc.beans.aop;
public interface ArithmeticCalculator {
 int add(int i, int j);
 int sub(int i, int j);
 int mul(int i, int j);
 int div(int i, int j);
}
package com.qcc.beans.aop;
import org.springframework.stereotype.Component;
//將實現(xiàn)類加入Spring的IOC容器進行管理
@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
 @Override
 public int add(int i, int j) {
 int result = i + j;
 return result;
 }
 @Override
 public int sub(int i, int j) {
 int result = i - j;
 return result;
 }
 @Override
 public int mul(int i, int j) {
 int result = i * j;
 return result;
 }
 @Override
 public int div(int i, int j) {
 int result = i / j;
 return result;
 }
}

4、現(xiàn)在想在實現(xiàn)類中的每個方法執(zhí)行前、后、以及是否發(fā)生異常等信息打印出來,需要把日志信息抽取出來,寫到對應(yīng)的切面的類中 LoggingAspect.java 中

要想把一個類變成切面類,需要兩步,

① 在類上使用 @Component 注解 把切面類加入到IOC容器中

② 在類上使用 @Aspect 注解 使之成為切面類

下面直接上完整代碼,用@Aspect注解方式來實現(xiàn)前置通知、返回通知、后置通知、異常通知、環(huán)繞通知。

package com.qcc.beans.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
 * 日志切面
 * 
 * @author QianChaoChen 00002336<br>
 * @date 2017年3月3日 下午3:03:29
 */
@Component
@Aspect
public class LoggingAspect {
 /**
 * 前置通知:目標(biāo)方法執(zhí)行之前執(zhí)行以下方法體的內(nèi)容 
 * @param jp
 */
 @Before("execution(* com.qcc.beans.aop.*.*(..))")
 public void beforeMethod(JoinPoint jp){
 String methodName = jp.getSignature().getName();
 System.out.println("【前置通知】the method 【" + methodName + "】 begins with " + Arrays.asList(jp.getArgs()));
 }
 /**
 * 返回通知:目標(biāo)方法正常執(zhí)行完畢時執(zhí)行以下代碼
 * @param jp
 * @param result
 */
 @AfterReturning(value="execution(* com.qcc.beans.aop.*.*(..))",returning="result")
 public void afterReturningMethod(JoinPoint jp, Object result){
 String methodName = jp.getSignature().getName();
 System.out.println("【返回通知】the method 【" + methodName + "】 ends with 【" + result + "】");
 }
 /**
 * 后置通知:目標(biāo)方法執(zhí)行之后執(zhí)行以下方法體的內(nèi)容,不管是否發(fā)生異常。
 * @param jp
 */
 @After("execution(* com.qcc.beans.aop.*.*(..))")
 public void afterMethod(JoinPoint jp){
 System.out.println("【后置通知】this is a afterMethod advice...");
 }
 /**
 * 異常通知:目標(biāo)方法發(fā)生異常的時候執(zhí)行以下代碼
 */
 @AfterThrowing(value="execution(* com.qcc.beans.aop.*.*(..))",throwing="e")
 public void afterThorwingMethod(JoinPoint jp, NullPointerException e){
 String methodName = jp.getSignature().getName();
 System.out.println("【異常通知】the method 【" + methodName + "】 occurs exception: " + e);
 }
// /**
// * 環(huán)繞通知:目標(biāo)方法執(zhí)行前后分別執(zhí)行一些代碼,發(fā)生異常的時候執(zhí)行另外一些代碼
// * @return 
// */
// @Around(value="execution(* com.qcc.beans.aop.*.*(..))")
// public Object aroundMethod(ProceedingJoinPoint jp){
// String methodName = jp.getSignature().getName();
// Object result = null;
// try {
//  System.out.println("【環(huán)繞通知中的--->前置通知】:the method 【" + methodName + "】 begins with " + Arrays.asList(jp.getArgs()));
//  //執(zhí)行目標(biāo)方法
//  result = jp.proceed();
//  System.out.println("【環(huán)繞通知中的--->返回通知】:the method 【" + methodName + "】 ends with " + result);
// } catch (Throwable e) {
//  System.out.println("【環(huán)繞通知中的--->異常通知】:the method 【" + methodName + "】 occurs exception " + e);
// }
// 
// System.out.println("【環(huán)繞通知中的--->后置通知】:-----------------end.----------------------");
// return result;
// }
}

5、編寫Main方法進行測試

package com.qcc.beans.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
 public static void main(String[] args) {
 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
 ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
 System.out.println(arithmeticCalculator.getClass());
 int result = arithmeticCalculator.add(3, 5);
 System.out.println("result: " + result);
 result = arithmeticCalculator.div(5, 0);
 System.out.println("result: " + result);
 }
}
 

運行結(jié)果:

class com.sun.proxy.$Proxy10
【前置通知】the method 【add】 begins with [3, 5]
【后置通知】this is a afterMethod advice...
【返回通知】the method 【add】 ends with 【8】
result: 8
【前置通知】the method 【div】 begins with [5, 0]
【后置通知】this is a afterMethod advice...
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.qcc.beans.aop.ArithmeticCalculatorImpl.div(ArithmeticCalculatorImpl.java:28)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
 at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
 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:207)
 at com.sun.proxy.$Proxy10.div(Unknown Source)
 at com.qcc.beans.aop.Main.main(Main.java:15)

把其它代碼都注釋掉,把環(huán)繞通知的方法釋放出來,測試結(jié)果如下:

【環(huán)繞通知中的--->前置通知】:the method 【add】 begins with [3, 5]
【環(huán)繞通知中的--->返回通知】:the method 【add】 ends with 8
【環(huán)繞通知中的--->后置通知】:-----------------end.----------------------
result: 8
【環(huán)繞通知中的--->前置通知】:the method 【div】 begins with [5, 0]
【環(huán)繞通知中的--->異常通知】:the method 【div】 occurs exception java.lang.ArithmeticException: / by zero
【環(huán)繞通知中的--->后置通知】:-----------------end.----------------------
Exception in thread "main" org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract int com.qcc.beans.aop.ArithmeticCalculator.div(int,int)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:219)
 at com.sun.proxy.$Proxy7.div(Unknown Source)
 at com.qcc.beans.aop.Main.main(Main.java:15)

從以上發(fā)現(xiàn),返回通知和異常通知不會同時出現(xiàn);不管是否發(fā)生異常,后置通知都會正常打印。

補充:基于@Aspect實現(xiàn)AOP的兩種方式

第一種:

package com.anno; 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; 
@Retention(RetentionPolicy.RUNTIME) //什么時候運行和結(jié)束
@Target( {ElementType.METHOD , ElementType.TYPE}) //能放在哪里.
public @interface AnnotationTwo {
}
package com.anno; 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component; 
@Aspect
@Component
@EnableAspectJAutoProxy
public class AspectAnnotationTOW { 
 @Pointcut("@annotation(AnnotationTwo)")
 public void aspectTow(){
 
 }
 
 @Around("aspectTow()")
 public void aspectservice(ProceedingJoinPoint joinPoint){
 System.out.println(111);
 try {
 Object proceed = joinPoint.proceed();
 } catch (Throwable e) {
 e.printStackTrace();
 }
 }
 
}

第二種:

package com.testAnnotation; 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; 
 
@Retention(RetentionPolicy.RUNTIME) //什么時候運行和結(jié)束
@Target( {ElementType.METHOD , ElementType.TYPE}) //能放在哪里.
public @interface AnnotationOfTest {
 public String say();
 public long howLong() default Long.MAX_VALUE;
}
package com.testAnnotation; 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component; 
import com.rabbitmq.tools.jsonrpc.ProcedureDescription; 
@Component
@EnableAspectJAutoProxy
@Aspect
public class AspectAnnotation {
 @Around("@annotation(annotationOfTest)")
 public Object interceptor(ProceedingJoinPoint pjp, AnnotationOfTest annotationOfTest ) {
 String say = annotationOfTest.say();
 long howlong = annotationOfTest.howLong();
 try {
 System.out.println(say+"\t"+howlong);
 Object object = pjp.proceed();
 return object;
 } catch (Throwable e) {
 e.printStackTrace();
 }
 return null;
 }
 }

配置文件:

<?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:util="http://www.springframework.org/schema/util"
 xmlns:p="http://www.springframework.org/schema/p" 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-4.3.xsd
 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 
 <context:component-scan base-package="com.testAnnotation"></context:component-scan>
 <context:component-scan base-package="com.service"></context:component-scan>
 <context:component-scan base-package="com.anno"></context:component-scan> 
 <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> 
 
 </beans> 
service:
package com.service; 
import java.util.Date; 
import org.springframework.stereotype.Service; 
import com.anno.AnnotationTwo;
import com.testAnnotation.AnnotationOfTest;
 
@Service
public class service {
 @AnnotationTwo
 public void go()
 {
 System.out.println(new Date().toLocaleString());
 } 
}

項目結(jié)構(gòu):

測試:

package com.test;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.service.service;
import com.testAnnotation.AnnotationOfTest;
 
public class Test {
 public static void main(String[] args) {
 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
 service bean = applicationContext.getBean(service.class);
 bean.go();
 }
}

所需要的包:

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • MyBatis中insert操作返回主鍵的實現(xiàn)方法

    MyBatis中insert操作返回主鍵的實現(xiàn)方法

    在使用MyBatis做持久層時,insert語句默認(rèn)是不返回記錄的主鍵值,而是返回插入的記錄條數(shù)。這篇文章主要介紹了MyBatis中insert操作返回主鍵的方法,需要的朋友可以參考下
    2016-09-09
  • Spring MVC+mybatis實現(xiàn)注冊登錄功能

    Spring MVC+mybatis實現(xiàn)注冊登錄功能

    這篇文章主要為大家詳細(xì)介紹了Spring MVC+mybatis實現(xiàn)注冊登錄功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 使用Java WebSocket獲取客戶端IP地址的示例代碼

    使用Java WebSocket獲取客戶端IP地址的示例代碼

    在開發(fā)Web應(yīng)用程序時,我們通常需要獲取客戶端的 IP 地址用于日志記錄、身份驗證、限制訪問等操作,本文將介紹如何使用Java WebSocket API獲取客戶端IP地址,以及如何在常見的WebSocket框架中獲得客戶端 IP地址,需要的朋友可以參考下
    2023-11-11
  • 老生常談java數(shù)組中的常見異常

    老生常談java數(shù)組中的常見異常

    數(shù)組是用來存儲一系列數(shù)據(jù),但它往往被認(rèn)為是一系列相同類型的變量,異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并且錯誤有時候是可以避免的,接下來讓我們詳細(xì)的了解吧
    2022-03-03
  • springboot項目開啟https協(xié)議的項目實現(xiàn)

    springboot項目開啟https協(xié)議的項目實現(xiàn)

    本文主要介紹了springboot項目開啟https協(xié)議的項目實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • cookie、session和java過濾器結(jié)合實現(xiàn)登陸程序

    cookie、session和java過濾器結(jié)合實現(xiàn)登陸程序

    這篇文章主要為大家詳細(xì)介紹了cookie、session和java過濾器結(jié)合實現(xiàn)登陸程序的具體代碼,感興趣的朋友可以參考一下
    2016-05-05
  • SpringCloud中NacosNamingService的作用詳解

    SpringCloud中NacosNamingService的作用詳解

    這篇文章主要介紹了SpringCloud中NacosNamingService的作用詳解,NacosNamingService類完成服務(wù)實例注冊,撤銷與獲取服務(wù)實例操作,NacosNamingService初始化采用單例模式,使用反射生成,需要的朋友可以參考下
    2023-11-11
  • 詳解idea+maven打jar包的兩種方式

    詳解idea+maven打jar包的兩種方式

    這篇文章主要介紹了idea+maven打jar包的兩種方式,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java數(shù)據(jù)結(jié)構(gòu)及算法實例:插入排序 Insertion Sort

    Java數(shù)據(jù)結(jié)構(gòu)及算法實例:插入排序 Insertion Sort

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)及算法實例:插入排序 Insertion Sort,本文直接給出實例代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下
    2015-06-06
  • Spring AOP實現(xiàn)記錄操作日志

    Spring AOP實現(xiàn)記錄操作日志

    這篇文章主要為大家詳細(xì)介紹了Spring AOP實現(xiàn)記錄操作日志,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論

旬邑县| 黄冈市| 克山县| 马山县| 来宾市| 三河市| 平乐县| 南开区| 饶平县| 兰州市| 临城县| 沧州市| 广饶县| 会理县| 商丘市| 郧西县| 道孚县| 安龙县| 微山县| 普兰店市| 灵宝市| 揭东县| 淮滨县| 乌兰察布市| 辽宁省| 稻城县| 肇源县| 仪陇县| 陕西省| 来安县| 九龙县| 五台县| 濮阳县| 城市| 兴安县| 石河子市| 竹山县| 洛南县| 兴城市| 名山县| 富锦市|