- Spring Boot進階:原理、實戰與面試題分析
- 鄭天民
- 601字
- 2022-07-05 09:41:48
3.2.3 ProxyFactoryBean
JDK自帶的動態代理以及基于CGLIB的動態代理在Spring框架中都得到了應用,最典型的應用場景就是實現AOP。Spring專門提供了一個ProxyFactoryBean類用于手動創建對象代理,并將創建的代理對象作為目標對象的AOP代理。
ProxyFactoryBean提供了一組配置屬性用于指定代理的執行行為,比較常見的包括proxyTargetClass和exposeProxy。如果proxyTargetClass屬性為true,則僅使用CGLIB創建代理。如果該屬性未設置,那么有兩種情況:如果目標類實現了接口,則將使用JDK創建代理;反之,將使用CGLIB創建代理。而exposeProxy屬性用于設置是否將當前代理暴露給ThreadLocal。如果該屬性為true,那么開發人員可以使用AopContext.currentProxy()方法來獲取代理對象。
接下來,我們演示如何使用ProxyFactoryBean來創建和管理代理對象。我們繼續沿用3.1.2節中所介紹的案例場景?,F在讓我們為MethodBeforeAdvice接口提供一個實現類。顯然從命名上看,這個實現類是方法執行前通知的,如代碼清單3-11所示。
代碼清單3-11 MethodBeforeAdvice接口實現類代碼
public class AccountTransactionInterceptor implements MethodBeforeAdvice{ private static final Logger LOGGER = Logger.getLogger(AccountTransactionInterceptor.class); @Override public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { LOGGER.info("賬戶交易被攔截"); } }
接著,我們通過Java代碼創建一個通知,實現方式如代碼清單3-12所示。
代碼清單3-12 Advisor實現類代碼
@Bean public Advisor accountServiceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* com.springboot.aop.service.AccountService.doAccountTransaction(..))"); return new DefaultPointcutAdvisor(pointcut, new AccountTransactionInterceptor()); }
最后,我們創建一個ProxyFactoryBean實例,并設置相關屬性,如代碼清單3-13所示。
代碼清單3-13 ProxyFactoryBean實例代碼
@Bean public ProxyFactoryBean accountService(){ ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); proxyFactoryBean.setTarget(new AccountServiceImpl()); proxyFactoryBean.addAdvisor(accountServiceAdvisor()); proxyFactoryBean.setExposeProxy(true); return proxyFactoryBean; }
注意,這里我們設置目標類為AccountService接口的實現類AccountServiceImpl,并把exposeProxy屬性設置為true。這樣,我們在AccountServiceImpl中就可以使用Spring AOP提供的AopContext.currentProxy()方法來獲取這個代理對象,示例代碼如代碼清單3-14所示。
代碼清單3-14 AccountService實現類代碼
public class AccountServiceImpl implements AccountService{ ... @Override public boolean doAccountTransaction(Account source, Account dest, int amount) { ((AccountService)(AopContext.currentProxy())).doAccountTransaction(source, dest, amount); return true; } }
- Getting Started with Gulp(Second Edition)
- Apache ZooKeeper Essentials
- Node.js Design Patterns
- 跟小海龜學Python
- Learning Informatica PowerCenter 10.x(Second Edition)
- C語言程序設計實踐教程
- 人人都是網站分析師:從分析師的視角理解網站和解讀數據
- Rust Essentials(Second Edition)
- C語言程序設計上機指導與習題解答(第2版)
- UI設計全書(全彩)
- Image Processing with ImageJ
- Lift Application Development Cookbook
- Getting Started with React VR
- Getting Started with Electronic Projects
- C語言程序設計教程