成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring創(chuàng)建AOP代理并非只有@Aspect一種方式

開發(fā) 前端
ProxyFactoryBean與其他Spring FactoryBean實(shí)現(xiàn)一樣,引入了一個(gè)間層。簡單說如果你定義了一個(gè)名為foo的ProxyFactoryBean,那么引用foo的對象看不到ProxyFactoryBean實(shí)例本身,而是由ProxyFactoryBean中的getObject()方法實(shí)現(xiàn)創(chuàng)建的對象。

環(huán)境:Spring6.1.2


1. 簡介

在Spring項(xiàng)目中,使用@Aspect注解定義切面(Aspect)并創(chuàng)建AOP(面向切面編程)代理是一種常見的做法,它主要用于實(shí)現(xiàn)跨多個(gè)類和方法的橫切關(guān)注點(diǎn)(Cross-cutting Concerns)的模塊化。下面是對使用@Aspect定義切面以及創(chuàng)建AOP代理的示例:

@Aspect
public class LogAspect {
  // 定義切點(diǎn)
  @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("發(fā)生異常: " + tx.getMessage()) ;
  }
  // 環(huán)繞通知
  @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 ;
  }
}

以上是一個(gè)簡單的異常通知切面定義。在實(shí)際工作中絕大多數(shù)情況下都是通過上面的方式操作。

但是在某些場景下,你可能需要更細(xì)粒度的控制來創(chuàng)建代理對象,比如根據(jù)特定條件動態(tài)決定是否創(chuàng)建代理、自定義代理的創(chuàng)建過程或調(diào)整代理的行為。這時(shí),使用ProxyFactoryBeanProxyFactory可以提供更大的靈活性。ProxyFactoryBean主要用于在Spring容器中配置和創(chuàng)建代理對象,而ProxyFactory則提供了編程式創(chuàng)建代理對象的能力。如果你需要在代碼中動態(tài)地創(chuàng)建代理對象,而不是通過Spring容器來管理,那么使用ProxyFactory可能更合適。

接下來將詳細(xì)介紹通過ProxyFactoryBean和ProxyFactory創(chuàng)建AOP代理對象。

2. 代理對象創(chuàng)建

2.1 ProxyFactoryBean創(chuàng)建代理

該類提供了對切入點(diǎn)、任何適用的建議及其順序的完全控制。然而,如果您不需要這樣的控制,也可以選擇更簡單的選項(xiàng)。

ProxyFactoryBean與其他Spring FactoryBean實(shí)現(xiàn)一樣,引入了一個(gè)間層。簡單說如果你定義了一個(gè)名為foo的ProxyFactoryBean,那么引用foo的對象看不到ProxyFactoryBean實(shí)例本身,而是由ProxyFactoryBean中的getObject()方法實(shí)現(xiàn)創(chuàng)建的對象。此方法創(chuàng)建一個(gè)AOP代理,用于包裝目標(biāo)對象。

ProxyFactoryBean很多關(guān)鍵的屬性繼承自ProxyConfig(Spring中所有aop代理工廠的超類)。這些關(guān)鍵屬性結(jié)束如下:

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

以上是對ProxyFactoryBean創(chuàng)建代理對象時(shí)的核心配置說明。

完整使用案例如下:

public interface CommonDAO {}
  
public class PersonService {
  public void save() {
    System.out.println("save method invoke...") ;
  }
}
@Configuration
public 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創(chuàng)建代理

用Spring很容易通過編程創(chuàng)建AOP代理。這讓你可以在不依賴Spring IoC的情況下使用Spring AOP。由目標(biāo)對象實(shí)現(xiàn)的接口會自動被代理。如下示例:

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) ;
  // 設(shè)置通知類(內(nèi)部會自動的包裝為Advisor)
  factory.addAdvice(new MethodInterceptor() {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
      System.out.println("權(quán)限控制...") ;
      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() ;
}

以上是本篇文章的全部內(nèi)容,希望對你有幫助。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2023-09-27 08:01:14

數(shù)據(jù)推送事件

2025-03-17 08:10:00

aviatorSpringJVM

2013-05-22 15:31:07

AOP的CGlib實(shí)現(xiàn)

2025-01-15 12:00:00

Java線程編程

2023-07-27 08:14:29

2022-08-18 09:38:02

Spring跨域

2015-05-06 10:05:22

javajava框架spring aop

2022-06-06 15:44:24

大數(shù)據(jù)數(shù)據(jù)分析思維模式

2022-02-14 10:30:37

Java方式框架

2019-08-20 14:13:12

工業(yè)物聯(lián)網(wǎng)IIOT藍(lán)牙

2023-08-02 10:48:47

SpringBean反射

2023-01-26 23:46:15

2009-12-25 16:27:30

MODEM接入方式

2013-12-12 17:58:02

網(wǎng)絡(luò)虛擬化疊加SDN

2009-02-26 10:29:00

2018-07-09 14:52:05

2021-07-30 16:09:18

加密貨幣比特幣貨幣

2020-12-09 10:15:34

Pythonweb代碼

2020-12-23 10:10:23

Pythonweb代碼

2022-07-07 10:33:27

Python姿勢代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 96av麻豆蜜桃一区二区 | 一区二区不卡视频 | 精品视频在线观看 | 天天看片天天干 | 国产亚洲一区二区三区 | 欧美日韩久久久 | 欧美日韩亚| 国产视频中文字幕 | 伊人狠狠操 | 一级黄色片美国 | 日本又色又爽又黄又高潮 | 亚洲精品久久久久久久久久久久久 | 欧美性video| 国产精品免费高清 | 亚洲一二三区免费 | 日韩亚洲一区二区 | 99久久精品免费看国产免费软件 | 国产欧美久久精品 | 一区二区三区四区av | 亚洲一一在线 | 精品国产乱码久久久久久久久 | 亚洲国产精品美女 | 一区中文字幕 | 国产精品国产馆在线真实露脸 | 欧美九九| 欧美在线激情 | 91精品久久久久久综合五月天 | 久久久久av| 亚洲二区视频 | 欧美日韩综合一区 | 欧美成人精品一区二区三区 | 福利网址 | 国产又色又爽又黄又免费 | 亚洲精品91 | 激情 亚洲 | 久久久久无码国产精品一区 | 另类视频在线 | 国产黄色av网站 | 国产成人精品一区二区三区在线 | 成人激情视频 | 日韩欧美一级片 |