Spring AOP手動(dòng)實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)代理的代碼
什么是AOP我們先來看一張圖

圖中A就是通知,比如你要給每個(gè)方法前都加一個(gè)before()方法,目標(biāo)類的每一個(gè)方法叫joinpoint(切入點(diǎn)),每個(gè)切入點(diǎn)都會(huì)用到通知,把通知和切入點(diǎn)連起來,點(diǎn)成線,線成面,這就是切面,也就是AOP,下面我們來簡(jiǎn)單寫個(gè)小例子來實(shí)現(xiàn)一下
目標(biāo)類的接口
public interface UserService {
public void addUser() ;
public void updateUser();
public void deleteUser();
}
目標(biāo)類接口的實(shí)現(xiàn)
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("addUser");
}
@Override
public void updateUser() {
System.out.println("updateUser");
}
@Override
public void deleteUser() {
System.out.println("deleteUser");
}
}
通知類
public class MyAspect {
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
}
代理類
public class MyBeanFactory {
public static UserService createService(){
//1.目標(biāo)類
final UserService userService = new UserServiceImpl() ;
//2.切面類
final MyAspect myAspect = new MyAspect();
// 切入點(diǎn)和切面類結(jié)合
// 三個(gè)參數(shù)
// 1. loader ,類加載器 運(yùn)行是加載,用類加載器將其加載到內(nèi)存
// 2. interfaces 代理類需要實(shí)現(xiàn)的所有接口
// 3. invocationHandler 處理類,一般采用匿名內(nèi)部類
// 提供了invoke方法 代理類每個(gè)方法執(zhí)行時(shí)都將調(diào)用一次invoke ,又有三個(gè)參數(shù)
// 1. Object proxy 代理對(duì)象
// 2. Method method 代理對(duì)象方法的反射
// 3. Object[] args 方法的實(shí)際參數(shù)
UserService proxyService = (UserService) Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName());
myAspect.before();
Object obj = method.invoke(userService, args);
myAspect.after();
return obj ;
}
});
return proxyService ;
}
}
測(cè)試類
public class UserServiceImplTest {
@org.junit.jupiter.api.Test
public void demo() throws Exception {
UserService userService = MyBeanFactory.createService();
userService.addUser();
userService.deleteUser();
userService.updateUser();
}
}
結(jié)果
addUser
before
addUser
after
deleteUser
before
deleteUser
after
updateUser
before
updateUser
after
Process finished with exit code 0
我們可以看到每個(gè)方法都執(zhí)行了通知,用了動(dòng)態(tài)代理就不用手動(dòng)的給每個(gè)方法前后加入通知,這樣既節(jié)省了時(shí)間,也保證了主體代碼不被改變
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
詳解如何使用ModelMapper庫進(jìn)行對(duì)象之間的屬性映射
這篇文章主要介紹了如何使用ModelMapper庫進(jìn)行對(duì)象之間的屬性映射實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端
這篇文章主要為大家詳細(xì)介紹了java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
Java 采用反射獲取class屬性值的實(shí)現(xiàn)代碼
以下是對(duì)在Java中采用反射獲取class屬性值的實(shí)現(xiàn)代碼進(jìn)行了分析介紹,需要的朋友可以過來參考下2013-08-08
java使用wait和notify實(shí)現(xiàn)線程通信
這篇文章主要為大家詳細(xì)介紹了java如何使用wait和notify實(shí)現(xiàn)線程之間通信,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享
這篇文章主要介紹了Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享的相關(guān)資料,需要的朋友可以參考下2022-12-12
SpringCloud?Feign請(qǐng)求頭刪除修改的操作代碼
這篇文章主要介紹了SpringCloud?Feign請(qǐng)求頭刪除修改,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
使用CORS實(shí)現(xiàn)JavaWeb跨域請(qǐng)求問題的方法
這篇文章主要介紹了使用Cors實(shí)現(xiàn)JavaWeb跨域請(qǐng)求問題的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09

