一筋蓖、動(dòng)態(tài)簡(jiǎn)單說明
- jdk動(dòng)態(tài)代理:利用反射機(jī)制荤西,基于接口創(chuàng)建被代理對(duì)象的代理實(shí)例(僅支持基于接口進(jìn)行代理澜搅,無法對(duì)類進(jìn)行代理)代理類通過實(shí)現(xiàn)InvocationHander.invok();
- cglib動(dòng)態(tài)代理:基于繼承的方式代理目標(biāo)類和方法,但是不能是final 類型的;
通過實(shí)現(xiàn)MethodInterceptor.interceptor();
CGLIB$intercept() 方法實(shí)際上是委托給 DynamicAdvisedInterceptor 的 intercept(),這個(gè)過程是由CGLIB庫(kù)通過字節(jié)碼生成技術(shù)(ASM)完成的邪锌。
二勉躺、動(dòng)態(tài)代理簡(jiǎn)單使用
public interface A {
public void a();
public void b();
}
public class Aimpl implements A{
@Override
public void a() {
System.out.println("執(zhí)行方法A~~~~");
}
@Override
public void b() {
System.out.println("執(zhí)行方法B~~~~");
}
}
jdk動(dòng)態(tài)代理:
public class JdkProxyTest implements InvocationHandler {
private A a;
public JdkProxyTest(A a){
this.a = a;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk代理-invoke執(zhí)行~~~~");
return method.invoke(a,args);
}
public static A newProxyInstance(A a){
return (A) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(),new Class[]{A.class},new JdkProxyTest(a));
}
public static void main(String[] args) {
A a = new Aimpl();
A jdkProxy = JdkProxyTest.newProxyInstance(a);
jdkProxy.a();
jdkProxy.b();
}
}
輸出:
cglib動(dòng)態(tài)代理:
public class CglibProxyTest implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib代理-interceptor執(zhí)行~~~~");
return methodProxy.invokeSuper(o,objects);
}
public static <T extends A> A newProxyInstance(Class<T> targetInstanceClazz){
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new CglibProxyTest());
enhancer.setSuperclass(targetInstanceClazz);
enhancer.setInterfaces(new Class[]{A.class});
return (A) enhancer.create();
}
public static void main(String[] args) {
A cglibAgent = CglibProxyTest.newProxyInstance(Aimpl.class);
cglibAgent.a();
cglibAgent.b();
}
}
輸出:
三、spring集成動(dòng)態(tài)代理源碼解析
- 使用@EnableAspectJAutoProxy 確認(rèn)使用哪種代理秃流。
- 參數(shù):proxyTargetClass true表示使用cglib代理赂蕴,false表示使用jdk代理柳弄;參數(shù)
- 參數(shù):exposeProxy 值為true 表示暴露代理類舶胀,目標(biāo)類中可以嵌套代理類,使用AopContext.currentProxy() 獲取代理類
- 源碼:
- AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
try {
...
finishBeanFactoryInitialization(beanFactory);
...
}
...
}
}
-
創(chuàng)建bean, AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutoProxyCreator.postProcessBeforeInstantiation()
-
AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()