新聞中心
- 基于接口(JDK)的動(dòng)態(tài)代理- 基于子類(CGLIB)的動(dòng)態(tài)代理對(duì)于 JDK 動(dòng)態(tài)代理,在選擇哪種類型進(jìn)行動(dòng)態(tài)代理時(shí)還要考慮到性能等因素。2. 封裝 Spring 動(dòng)態(tài)代理工具類在實(shí)際開發(fā)中。
- 本文目錄導(dǎo)讀:
- 1、Spring 動(dòng)態(tài)代理基礎(chǔ)知識(shí)
- 2、封裝 Spring 動(dòng)態(tài)代理工具類
- 3、總結(jié)

十年的嶗山網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷型網(wǎng)站的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整嶗山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“嶗山網(wǎng)站設(shè)計(jì)”,“嶗山網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
在軟件開發(fā)中,我們經(jīng)常需要使用動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)一些功能。而 Spring 框架提供了強(qiáng)大的動(dòng)態(tài)代理機(jī)制,使得我們可以非常方便地進(jìn)行 AOP 編程。但是,在實(shí)際開發(fā)中,我們可能會(huì)遇到很多重復(fù)性的代碼編寫問(wèn)題,這時(shí)候就需要一個(gè)萬(wàn)件工具類來(lái)解決這個(gè)問(wèn)題。
下面就介紹一下 Spring 中動(dòng)態(tài)代理的使用方法,并且通過(guò)封裝一個(gè)萬(wàn)樣工具類來(lái)減少代碼量和提高開發(fā)效率。
1. Spring 動(dòng)態(tài)代理基礎(chǔ)知識(shí)
在 Spring 中,有兩種類型的動(dòng)態(tài)代理:
- 基于接口(JDK)的動(dòng)態(tài)代理
- 基于子類(CGLIB)的動(dòng)態(tài)代理
對(duì)于 JDK 動(dòng)態(tài)代理,它只能為接口創(chuàng)建代理對(duì)象。也就是說(shuō),在被攔截對(duì)象沒有實(shí)現(xiàn)任何接口時(shí)無(wú)法使用 JDK 動(dòng)態(tài)代理。而 CGLIB 則可以為任何類創(chuàng)建子類作為其新的字節(jié)碼文件并生成相應(yīng)的 Bean 實(shí)例。
當(dāng)然,在選擇哪種類型進(jìn)行動(dòng)態(tài)代理時(shí)還要考慮到性能等因素。如果目標(biāo)對(duì)象實(shí)現(xiàn)了至少一個(gè)接口,則會(huì)采用 JDK 動(dòng)態(tài)生成代理類;否則,將使用 CGLIB 來(lái)生成代理類。但是無(wú)論哪種方式,Spring 都會(huì)為我們自動(dòng)生成代理對(duì)象,并且把它們注入到 IOC 容器中。
2. 封裝 Spring 動(dòng)態(tài)代理工具類
在實(shí)際開發(fā)中,我們可能需要對(duì)多個(gè)不同的 Bean 進(jìn)行動(dòng)態(tài)代理。如果每次都手寫一個(gè) ProxyFactoryBean 對(duì)象來(lái)進(jìn)行配置,則代碼量會(huì)非常大而且重復(fù)性很高。因此,我們可以封裝一個(gè)萬(wàn)件工具類來(lái)簡(jiǎn)化這個(gè)過(guò)程。
下面就給出一個(gè)例子:
```java
public class DynamicProxyUtil
private T target;
private ApplicationContext applicationContext;
public T getProxy(T target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return (T)enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 前置通知
Object result = method.invoke(target, args);
// 后置通知
return result;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
```
上述代碼中,DynamicProxyUtil 是一個(gè)泛型工具類,在構(gòu)造函數(shù)里通過(guò)傳遞目標(biāo)對(duì)象 T 初始化了變量 target。該工具類還實(shí)現(xiàn)了接口 ApplicationContextAware ,以便獲取 Spring 的上下文環(huán)境。
getProxy 方法則是根據(jù)傳入的目標(biāo)對(duì)象 target,返回一個(gè)代理對(duì)象。在該方法中使用了 CGLIB 動(dòng)態(tài)生成代理類,并且將其回調(diào)函數(shù)設(shè)置為當(dāng)前工具類(MethodInterceptor)。而 MethodInterceptor 接口可以實(shí)現(xiàn)對(duì)被攔截方法進(jìn)行前置通知和后置通知等操作。
這樣,在以后需要?jiǎng)討B(tài)代理某個(gè) Bean 時(shí),只需直接調(diào)用 DynamicProxyUtil 工具類即可:
@Service
public class UserServiceImpl implements UserService {
public void addUser(User user) {
// 添加用戶邏輯
@Autowired
private DynamicProxyUtil
@Test
public void testAddUser() {
UserService userService = new UserServiceImpl();
UserService proxy = dynamicProxyUtil.getProxy(userService);
proxy.addUser(new User());
如上所示,在測(cè)試代碼中,我們通過(guò)自動(dòng)注入方式獲取到了之前定義好的 DynamicProxyUtil 對(duì)象,并且使用它來(lái)創(chuàng)建了一個(gè)新的代理對(duì)象。然后就可以像平常一樣使用該對(duì)象來(lái)完成相應(yīng)業(yè)務(wù)邏輯。
3. 總結(jié)
總之,Spring 框架提供了強(qiáng)大的動(dòng)態(tài)代理機(jī)制讓我們能夠更加方便地進(jìn)行 AOP 編程。但是在實(shí)際開發(fā)中可能會(huì)遇到很多重復(fù)性的代碼編寫問(wèn)題。因此本文介紹了封裝 Spring 動(dòng)態(tài)代理萬(wàn)件工具類的方法,可以減少代碼量和提高開發(fā)效率。希望本文對(duì)大家有所幫助。
當(dāng)前標(biāo)題:Spring動(dòng)態(tài)代理萬(wàn)能工具類:讓你的代碼更簡(jiǎn)潔高效
網(wǎng)站鏈接:http://www.dlmjj.cn/article/cdpccco.html


咨詢
建站咨詢
