日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring-AOP 通过配置文件实现 引介增强

發布時間:2025/3/21 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring-AOP 通过配置文件实现 引介增强 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 概述
  • 實例

概述

引介增強是一種比較特殊的增強類型,它不是在目標方法周圍織入增強,而是為目標創建新的方法和屬性,所以它的連接點是類級別的而非方法級別的。

通過引介增強我們可以為目標類添加一個接口的實現即原來目標類未實現某個接口,那么通過引介增強可以為目標類創建實現某接口的代理。

Spring定義了引介增強接口IntroductionInterceptor,該接口沒有定義任何方法

Spring為該接口提供了DelegatingIntroductionInterceptor實現類,一般情況下,通過擴展該實現類定義自己的引介增強類。


實例

代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster

我們一直使用的性能檢測的例子。 開啟監控會影響業務系統的性能,我們可以設置是否啟用性能監視為可控的,那我們改如何使用引介增強實現這一個誘人的功能呢?

我們創建一個示例來演示下,步驟如下:
創建接口類:Monitorable.java
創建業務類:PerformanceMonitor.java
創建增強類:ControllablePerformanceMonitor.java
創建配置文件:conf-advice.xml
創建增強測試類:DelegatingTest.java

接口類:Monitorable.java

package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;public interface Monitorable {void setMonitorActive(boolean active); }

該接扣僅包含一個setMonitorActive方法,我們希望通過該接口方法控制業務類性能監視功能的激活和關閉狀態

接下來創建業務類

package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;public class PerformanceMonitor {private static ThreadLocal<MethodPerformace> performaceRecord = new ThreadLocal<MethodPerformace>();public static void begin(String method) {System.out.println("begin monitor...");MethodPerformace mp = performaceRecord.get();if (mp == null) {mp = new MethodPerformace(method);performaceRecord.set(mp);} else {mp.reset(method);}}public static void end() {System.out.println("end monitor...");MethodPerformace mp = performaceRecord.get();mp.printPerformace();} }

接下來創建增強類ControllablePerformanceMonitor

package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.support.DelegatingIntroductionInterceptor;public class ControllablePerformaceMonitor extendsDelegatingIntroductionInterceptor implements Monitorable {private static final long serialVersionUID = 1L;// 定義ThreadLocal類型的變量,用于保存性能監視開關狀態。 為了解決單實例線程安全的問題,通過ThreadLocal// 讓每個線程單獨使用一個狀態private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>();@Overridepublic void setMonitorActive(boolean active) {MonitorStatusMap.set(active);}/*** 攔截方法*/@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {Object obj = null;// 對于支持新跟那個監視可控代理,通過判斷其狀態決定是否開啟性能監控功能// Java5.0的自動拆包功能,get方法返回的Boolean被自動拆包為boolean類型的值if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) {PerformanceMonitor.begin(mi.getClass().getName() + "."+ mi.getMethod().getName());obj = super.invoke(mi);PerformanceMonitor.end();} else {obj = super.invoke(mi);}return obj;}}

接下來創建所要增強的方法類

package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;public class ForumService {public void removeTopic(int topicId) {System.out.println("模擬刪除Topic記錄:" + topicId);try {Thread.currentThread().sleep((long) (Math.random() * 1000 * 20));} catch (Exception e) {throw new RuntimeException(e);}}public void removeForum(int forumId) {System.out.println("模擬刪除Forum記錄:" + forumId);try {Thread.currentThread().sleep((long) (Math.random() * 1000 * 20));} catch (Exception e) {throw new RuntimeException(e);}} } package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;public class MethodPerformace {private long begin;private long end;private String serviceMethod;public MethodPerformace(String serviceMethod) {reset(serviceMethod);}public void printPerformace() {end = System.currentTimeMillis();long elapse = end - begin;System.out.println(serviceMethod + "花費" + elapse + "毫秒。");}public void reset(String serviceMethod) {this.serviceMethod = serviceMethod;this.begin = System.currentTimeMillis();} }

創建配置文件來將所設置的代碼組合起來

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="pmonitor"class="com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor.ControllablePerformaceMonitor" /><bean id="forumServiceTarget" class="com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor.ForumService" /><bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"p:interfaces="com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor.Monitorable"p:target-ref="forumServiceTarget" p:interceptorNames="pmonitor"p:proxyTargetClass="true" /></beans>

引介增強的配置和一般配置有較大的區別,

  • 首先需要指定引介增強所實現的接口 ,如 p:interfaces ,這里的引介增強實現了Monitorable接口。
  • 其次,由于只能通過為目標類創建子類的方式生成引介增強的代理,所以必須將 p:proxyTargetClass=”true”

如果沒有對ControllablePerformaceMonitor進行線程安全的處理,就必須將singleton屬性設置為false, 讓ProxyFactoryBean產生prototype的作用域類型的代理。 這里就帶來了一個嚴重的性能問題,因為cglib動態創建代理的性能很低,而每次getBean方法從容器中獲取作用域為prototype的Bean時都將返回一個新的代理實例,所以這種影響是巨大的,這也是為什么通過ThreadLocal對ControllablePerformaceMonitor的開關進行線程安全化處理的原因。 通過線程安全處理后,就可以使用默認的singleton Bean作用域,這樣創建代理的動作僅發生一次。

創建對應的測試類

package com.xgj.aop.spring.advice.DelegatingIntroductionInterceptor;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class DelegatingTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advice/DelegatingIntroductionInterceptor/conf-advice.xml");ForumService forumService = (ForumService) ctx.getBean("forumService");forumService.removeForum(10);forumService.removeTopic(1022);Monitorable moniterable = (Monitorable) forumService;moniterable.setMonitorActive(true);forumService.removeForum(10);forumService.removeTopic(1022);} }

運行結果


總結

以上是生活随笔為你收集整理的Spring-AOP 通过配置文件实现 引介增强的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。