Spring 的動(dòng)態(tài)代理ProxyFactory

1.首先區(qū)別一下Spring的動(dòng)態(tài)代理和Spring AOP

2.spring 動(dòng)態(tài)代理ProxyFactory其實(shí)封裝了 CGLIB和JDK,他會(huì)自動(dòng)判斷用那種動(dòng)態(tài)代理,所以開(kāi)發(fā)過(guò)程中可以直接使用Spring的動(dòng)態(tài)代理會(huì)更加方便。

4.這里說(shuō)明一下CGLIB是一個(gè)單獨(dú)的項(xiàng)目,Spring是把CGLIB的源碼copy了一份到Spring中,并非依賴CGLIB的項(xiàng)目(jar 包),從而避免CGLIB升級(jí)影響Spring。

5.

//目標(biāo)對(duì)象或者被代理對(duì)象

UserService target =new UserService();

ProxyFactory proxyFactory =new ProxyFactory();

//設(shè)置目標(biāo)對(duì)象

proxyFactory.setTarget(target);

//這里如果設(shè)置interface就是使用JDK 動(dòng)態(tài)代理。

//proxyFactory.setInterfaces(target.getClass().getInterfaces());

//設(shè)置通知Advice這里有很多Advice - before after around return..

proxyFactory.addAdvice(new MethodBeforeAdvice() {

@Override

? public void before(Method method,Object[] args,Object target)throws Throwable {

//這里和我們寫的JDK CGLIB不一樣,會(huì)在執(zhí)行before后自動(dòng)去執(zhí)行目標(biāo)對(duì)象的方法,不需要通過(guò)metod.invoke(targe,args)

? ? ? System.out.println("before");

}

});

proxyFactory.addAdvice(new AfterReturningAdvice() {

@Override

? public void afterReturning(Object returnValue,Method method,Object[] args,Object target)throws Throwable {

System.out.println("after returning");

}

});

//around

proxyFactory.addAdvice(new MethodInterceptor() {

@Nullable

@Override

? public Object invoke(@NotNull MethodInvocation invocation)throws Throwable {

System.out.println("around before");

Object proceed = invocation.proceed();//around非常特殊,他的這個(gè)是MethodInterceptor,調(diào)用proceed是讓他繼續(xù)執(zhí)行其他的advice

System.out.println("around after");

return proceed;

}

});

//如果是JDK動(dòng)態(tài)代理這里就會(huì)報(bào)錯(cuò),因?yàn)樯傻拇韺?duì)象是接口對(duì)應(yīng)的子類對(duì)象和UserService沒(méi)關(guān)系

UserService proxy = (UserService)proxyFactory.getProxy();

proxy.test();

4.proxyFactory.addAdvice()可以添加多個(gè)按順序執(zhí)行 - 看上面代碼,最終的執(zhí)行結(jié)果
before - around before - test - around after - after returning

注:before和around before的執(zhí)行順序取決于advice加入的順序

5.類似于CGLib,Spring動(dòng)態(tài)代理也可以指定切方法 Advisor = Adivce + PointCut

所以Advisor可以指定哪個(gè)Adivce應(yīng)用在哪個(gè)方法上

proxyFactory.addAdvisor(new PointcutAdvisor() {

@Override

? public Pointcut getPointcut() {

//指定匹配類型

? ? ? return new StaticMethodMatcherPointcut() {

@Override

? ? ? ? public boolean matches(Method method,Class targetClass) {

return method.getName().equals("test");

}

};

}

@Override

? public Advice getAdvice() {

//指定Advice,這里就不寫了。

? ? ? return null;

}

});

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容