日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Spring創建AOP代理并非只有@Aspect一種方式

來源: 責編: 時間:2024-04-02 17:22:53 177觀看
導讀環境:Spring6.1.21. 簡介在Spring項目中,使用@Aspect注解定義切面(Aspect)并創建AOP(面向切面編程)代理是一種常見的做法,它主要用于實現跨多個類和方法的橫切關注點(Cross-cutting Concerns)的模塊化。下面是對使用@Aspect定

環境:Spring6.1.2pBM28資訊網——每日最新資訊28at.com


1. 簡介pBM28資訊網——每日最新資訊28at.com

在Spring項目中,使用@Aspect注解定義切面(Aspect)并創建AOP(面向切面編程)代理是一種常見的做法,它主要用于實現跨多個類和方法的橫切關注點(Cross-cutting Concerns)的模塊化。下面是對使用@Aspect定義切面以及創建AOP代理的示例:pBM28資訊網——每日最新資訊28at.com

@Aspectpublic class LogAspect {  // 定義切點  @Pointcut("execution(* com.pack..*.*(..))")  public void log() {  }  // 前置通知  @Before("log()")  public void beforeLog() {    System.out.println("記錄日志Before...");  }  // 后置通知  @After("log()")  public void afterLog() {    System.out.println("記錄日志After");  }  // 異常通知  @AfterThrowing(pointcut = "log()", throwing = "tx")  public void ex(Throwable tx) {    System.err.println("發生異常: " + tx.getMessage()) ;  }  // 環繞通知  @Around("log() && args(name)")  public Object around(ProceedingJoinPoint pjp, String name) throws Throwable {    System.out.println("log before...") ;    System.out.println("name = " + name) ;    Object ret = pjp.proceed() ;    System.out.println("log after...") ;    return ret ;  }}

以上是一個簡單的異常通知切面定義。在實際工作中絕大多數情況下都是通過上面的方式操作。pBM28資訊網——每日最新資訊28at.com

但是在某些場景下,你可能需要更細粒度的控制來創建代理對象,比如根據特定條件動態決定是否創建代理、自定義代理的創建過程或調整代理的行為。這時,使用ProxyFactoryBeanProxyFactory可以提供更大的靈活性。ProxyFactoryBean主要用于在Spring容器中配置和創建代理對象,而ProxyFactory則提供了編程式創建代理對象的能力。如果你需要在代碼中動態地創建代理對象,而不是通過Spring容器來管理,那么使用ProxyFactory可能更合適。pBM28資訊網——每日最新資訊28at.com

接下來將詳細介紹通過ProxyFactoryBean和ProxyFactory創建AOP代理對象。pBM28資訊網——每日最新資訊28at.com

2. 代理對象創建pBM28資訊網——每日最新資訊28at.com

2.1 ProxyFactoryBean創建代理
pBM28資訊網——每日最新資訊28at.com

該類提供了對切入點、任何適用的建議及其順序的完全控制。然而,如果您不需要這樣的控制,也可以選擇更簡單的選項。pBM28資訊網——每日最新資訊28at.com

ProxyFactoryBean與其他Spring FactoryBean實現一樣,引入了一個間層。簡單說如果你定義了一個名為foo的ProxyFactoryBean,那么引用foo的對象看不到ProxyFactoryBean實例本身,而是由ProxyFactoryBean中的getObject()方法實現創建的對象。此方法創建一個AOP代理,用于包裝目標對象。pBM28資訊網——每日最新資訊28at.com

ProxyFactoryBean很多關鍵的屬性繼承自ProxyConfig(Spring中所有aop代理工廠的超類)。這些關鍵屬性結束如下:pBM28資訊網——每日最新資訊28at.com

ProxyFactoryBean proxy = new ProxyFactoryBean() ;// 如果要代理的是目標類,而不是目標類的接口,則為True。如果該屬性值設置為true,則創建CGLIB代理proxy.setProxyTargetClass(false) ;// 控制是否對通過CGLIB創建的代理應用積極優化。除非您完全理解相關AOP代理如何處理優化,否則不應該輕松地使用此設置。目前僅用于CGLIB代理。它對JDK動態代理沒有影響。proxy.setOptimize(false) ;// 如果代理配置被凍結,則不再允許更改配置。無論是作為輕微的優化,還是當您不希望調用者在創建代理后能夠操作代理(通過建議的接口)時,這都是有用的。此屬性的默認值為false,因此允許更改(例如添加額外的通知)。proxy.setFrozen(false) ;// 確定是否應該在ThreadLocal中暴露當前代理,以便目標可以訪問它。如果目標需要獲取代理,而exposeProxy屬性被設置為true,那么可以使用AopContext.currentProxy()方法。proxy.setExposeProxy(false) ;// 接口名稱的字符串數組。如果沒有提供,則使用目標類的CGLIB代理proxy.setProxyInterfaces(new Class<?>[] {}) ;// 要應用的Advisor、攔截器或其他Advice名稱的字符串數組。點菜很重要,先到先得。也就是說,列表中的第一個攔截器是第一個能夠攔截調用的。proxy.setInterceptorNames("interceptor01") ;// 不管getObject()方法被調用的頻率如何,工廠是否應該返回一個對象。有幾個FactoryBean實現提供了這樣的方法。默認值為trueproxy.setSingleton(true) ;

以上是對ProxyFactoryBean創建代理對象時的核心配置說明。pBM28資訊網——每日最新資訊28at.com

完整使用案例如下:pBM28資訊網——每日最新資訊28at.com

public interface CommonDAO {}  public class PersonService {  public void save() {    System.out.println("save method invoke...") ;  }}@Configurationpublic class AppConfig {  @Bean  public MethodInterceptor logInterceptor() {    return new MethodInterceptor() {      @Override      public Object invoke(MethodInvocation invocation) throws Throwable {        System.out.println("日志記錄...") ;        return invocation.proceed() ;      }    };  }  @Bean  public ProxyFactoryBean personService() throws Exception {    ProxyFactoryBean proxy = new ProxyFactoryBean() ;    proxy.setProxyTargetClass(true) ;    proxy.setTargetSource(new SingletonTargetSource(new PersonService())) ;    proxy.setProxyInterfaces(new Class<?>[] {CommonDAO.class}) ;    proxy.setInterceptorNames("logInterceptor") ;    return proxy ;  }}

2.2 ProxyFactory創建代理pBM28資訊網——每日最新資訊28at.com

用Spring很容易通過編程創建AOP代理。這讓你可以在不依賴Spring IoC的情況下使用Spring AOP。由目標對象實現的接口會自動被代理。如下示例:pBM28資訊網——每日最新資訊28at.com

public interface CommonDAO {}public class PersonService {  public void save() {    System.out.println("save method invoke...") ;  }}public static void main(String[] args) {  ProxyFactory factory = new ProxyFactory(new PersonService()) ;  factory.setProxyTargetClass(true) ;  // 設置通知類(內部會自動的包裝為Advisor)  factory.addAdvice(new MethodInterceptor() {    @Override    public Object invoke(MethodInvocation invocation) throws Throwable {      System.out.println("權限控制...") ;      return invocation.proceed() ;    }  });  factory.addAdvisor(new PointcutAdvisor() {    @Override    public Advice getAdvice() {      return new MethodInterceptor() {        @Override        public Object invoke(MethodInvocation invocation) throws Throwable {          System.out.println("日志記錄...") ;          return invocation.proceed() ;        }      } ;    }    @Override    public Pointcut getPointcut() {      return new StaticMethodMatcherPointcut() {        @Override        public boolean matches(Method method, Class<?> targetClass) {          return method.getName().equals("save") ;        }      } ;    }  }) ;  PersonService ps = (PersonService) factory.getProxy() ;  ps.save() ;}

以上是本篇文章的全部內容,希望對你有幫助。pBM28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-80879-0.htmlSpring創建AOP代理并非只有@Aspect一種方式

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 這七種UML圖的畫法,每個程序員都應該掌握!

下一篇: 三萬字80道Java基礎經典面試題總結(2024修訂版)

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 秦皇岛市| 米易县| 融水| 金川县| 凌海市| 达拉特旗| 汪清县| 永清县| 巴林右旗| 偃师市| 庆元县| 漳平市| 曲麻莱县| 广州市| 白水县| 获嘉县| 东海县| 灯塔市| 西峡县| 修文县| 凉城县| 平潭县| 揭阳市| 莎车县| 娄烦县| 藁城市| 昆明市| 陇南市| 阳原县| 五原县| 木里| 仲巴县| 蒲江县| 永定县| 柞水县| 波密县| 调兵山市| 镇安县| 潢川县| 佛学| 正定县|