最近再项目中发现不少同事(包括自己)不太理解默认情况下的Spring事务的运行机制(主要是不理解AOP机制),导致随意使用事务注解.因此也在很多场景事务不生效。因此想从代理机制开始理一下整个Spring声明式事务的原理。
因为篇幅太长,分成三个部分:
(1).代理
(2).Spring的AOP
(3).Spring的事务
 
1.代理 
通常,我们代码中处理核心的业务逻辑,还包含一些枝节性的代码和功能,比如日志记录、消息发送、安全、事务保证和监控等。
我们通常期望将这些枝节性的代码功能和我们的核心业务逻辑分离,减少业务功能和枝节功能的耦合。这时候我们就要使用代理来达到我们的目的。
代理的作用是:为其它对象提供一种代理以控制对这个对象的访问。简单理解就是中间的作用。代理一般涉及到三个角色:
(1).抽象角色:声明真实对象和代理对象的共同接口;
(2).代理角色:代理对象内部包含有真实角色的引用,从而可以操作真实角色,同时代理对象与真实对象有相同的接口,能在任何时候代替真实对象,同时代理对象可以在执行真实对 象前后加入特定的逻辑以实现功能的扩展;
(3).真实角色:代理角色所代表的真实对象,是我们最终要引用的对象;
 
1.1 代理模式 
代理模式是一个经典的设计模式,介绍往上很多。
下面是一个最简单的实现:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
public interface IHello {
     void hello();
 }
 
 public class HelloImpl implements IHello {
     @Override
     public void hello() {
         System.out.println("HelloImpl: Hello World.");
     }
 }
 
 public class HelloProxyImpl implements IHello {
 
     private IHello inner;
 
     public HelloProxyImpl(IHello inner) {
         this.inner = inner;
     }
 
     @Override
     public void hello() {
         doSomethingBefore();
         
         inner.hello();
         
         doSomethingAfter();
     }
 
     private void doSomethingBefore() {
         System.out.println("HelloProxyImpl: Before hello()...");
     }
 
     private void doSomethingAfter() {
         System.out.println("HelloProxyImpl: After hello()...");
     }
 
 } 
 
UML图大致如下:
从代码上我们可以看出,代理模式要求(这也是它的限制所在):
(1).代理类需要和被代理者一样实现相同的接口;
(2).代理类包含被代理者的引用;
 
1.2 Java动态代理 
代理模式我们可以理解为一种静态代理,其问题是需要我们显示的为每个需要被代理的类实现一个代理类,即一个代理类只能为i一个被代理者做代理的功能。如果有上千个类需要代理,估计要骂娘了。
java动态代理正是为了解决这个问题。主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。我们只需要实现InvocationHandler接口,在实现invoke()方法的时候加上我们的代理逻辑。
一个简单的使用实例如下:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
/**
  * @author xiaobaoqiu  Date: 16-3-10 Time: 下午6:18
  */
 public class JavaDynamicProxy implements InvocationHandler {
 
     /**
      * 被代理者
      */
     private Object inner;
 
     /**
      * 生成代理类
      */
     public static Object generateProxy(Object inner) {
         return Proxy.newProxyInstance(
                 inner.getClass().getClassLoader(),
                 inner.getClass().getInterfaces(),
                 new JavaDynamicProxy(inner));
     }
 
     private JavaDynamicProxy(Object inner) {
         this.inner = inner;
     }
 
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         doSomethingBefore();
 
         Object result = method.invoke(inner, args);
 
         doSomethingAfter();
 
         return result;
     }
 
     private void doSomethingBefore() {
         System.out.println("JavaDynamicProxy: Before...");
     }
 
     private void doSomethingAfter() {
         System.out.println("JavaDynamicProxy: After...");
     }
 }
 
 //使用
 public static void main(String[] args) {
         //被动态代理的IHello实例对象A
         IHello helloA = new HelloImpl();
         //生成对象A的动态代理
         IHello helloAProxy = (IHello) JavaDynamicProxy.generateProxy(helloA);
         helloAProxy.hello();
 
         System.out.println("-------------------------------------------------");
         // 一个JavaDynamicProxy可以一直使用
 
         //被动态代理的IHello实例对象B
         IHello helloB = new HelloWithLogImpl();
         //生成对象B的动态代理
         IHello helloBProxy = (IHello) JavaDynamicProxy.generateProxy(helloB);
         helloBProxy.hello();
 
         System.out.println("-------------------------------------------------");
         //被动态代理对象IBye实例
         IBye bye = new ByeImpl();
         //生成IBye实例的动态代理
         IBye byeProxy = (IBye) JavaDynamicProxy.generateProxy(bye);
         byeProxy.bye();
 } 
 
JavaDynamicProxy.generateProxy的输出会是一个动态的代理类。debug信息如下,从debug信息我们大致知道,这个代理类的类名称为$Proxy0,内部包含一个属性名为h的属性,h指向的就是我们实现的InvocationHandler的类(这里即JavaDynamicProxy)的实例。
但是Java动态代理的限制是:
(1).被代理的类要求至少实现了一个Interface;
(2).被代理的类要求有public的构造函数(即没有显示的将其设置为private等);
(3).被代理的类要求不是final;
 
如下代理一个没有实现任何接口的类会报错
1 
2 
3 
4 
5 
6 
    //没有实现任何interface的类使不能被动态代理的
     System.out.println("-------------------------------------------------");
     HelloWithoutInterface helloC = new HelloWithoutInterface();
     //生成对象C的动态代理
     HelloWithoutInterface helloCProxy = (HelloWithoutInterface) JavaDynamicProxy.generateProxy(helloC);
     helloCProxy.hello(); 
 
错误信息如下:
1 
2 
3 
4 
5 
6 
7 
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy2 cannot be cast to proxy.javaProxy.HelloWithoutInterface
   at proxy.javaProxy.JavaProxyMain.main(JavaProxyMain.java:42)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
 
Java动态代理的机制是利用反射机制生成。具体代码可以debug,主要的代码如下:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
//Proxy.java
 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
   ...
   Class<?> cl = getProxyClass0(loader, intfs);  //生成代理类
   ...
   return newInstance(cons, ih);   // 生成代理类的实例
 }
 
 private static Class<?> getProxyClass0(ClassLoader loader,  Class<?>... interfaces) {
         //生成代理类的主要逻辑在ProxyClassFactory
         return proxyClassCache.get(loader, interfaces);
 }
 
 //ProxyClassFactory的apply方法
 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
   ...
             String proxyPkg = null;     // 生成代理类的包路径
             ...
             if (proxyPkg == null) {
                 // if no non-public proxy interfaces, use com.sun.proxy package
                 proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";   //默认路径在com.sun.proxy下面
             }
 
             long num = nextUniqueNumber.getAndIncrement();    //代理类的序号, 我们熟悉的$Proxy0中的0
             String proxyName = proxyPkg + proxyClassNamePrefix + num; //代理类的类名称
 
             //使用ProxyGenerator生成代理类的字节码
             byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces);
             //生成代理类
             return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
 }
 
 //ProxyGenerator.generateProxyClass的代码太恶心的... 
 
我们可以自己使用ProxyGenerator来生成代理类并将其字节码记录下来:
1 
2 
3 
// 获取代理类的字节码
 byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", ByeImpl.class.getInterfaces());
 //将字节码写文件,建议写成.class文件 
 
获取的字节码如下:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.UndeclaredThrowableException;
 import proxy.sample.IBye;
 
 public final class $Proxy0 extends Proxy implements IBye {
     private static Method m1;
     private static Method m3;
     private static Method m0;
     private static Method m2;
 
     public $Proxy0(InvocationHandler var1) throws  {
         super(var1);
     }
 
     public final boolean equals(Object var1) throws  {
         try {
             return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
         } catch (RuntimeException | Error var3) {
             throw var3;
         } catch (Throwable var4) {
             throw new UndeclaredThrowableException(var4);
         }
     }
 
     public final void bye() throws  {
         try {
             super.h.invoke(this, m3, (Object[])null);
         } catch (RuntimeException | Error var2) {
             throw var2;
         } catch (Throwable var3) {
             throw new UndeclaredThrowableException(var3);
         }
     }
 
     public final int hashCode() throws  {
         try {
             return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
         } catch (RuntimeException | Error var2) {
             throw var2;
         } catch (Throwable var3) {
             throw new UndeclaredThrowableException(var3);
         }
     }
 
     public final String toString() throws  {
         try {
             return (String)super.h.invoke(this, m2, (Object[])null);
         } catch (RuntimeException | Error var2) {
             throw var2;
         } catch (Throwable var3) {
             throw new UndeclaredThrowableException(var3);
         }
     }
 
     static {
         try {
             m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
             m3 = Class.forName("proxy.sample.IBye").getMethod("bye", new Class[0]);
             m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
             m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
         } catch (NoSuchMethodException var2) {
             throw new NoSuchMethodError(var2.getMessage());
         } catch (ClassNotFoundException var3) {
             throw new NoClassDefFoundError(var3.getMessage());
         }
     }
 } 
 
从生成的类我们知道,代理类继承Proxy类(这就是为什么Proxy类内的InvocationHandler实例未protected)并实现我们需要的被代理者的Interface(比如这里的bye()方法),另外它只要一个接受一个InvocationHandler为参数的构造函数。当我们调用代理类的bye()方法时候,其实是调用我们实现的InvocationHandler(即上面的JavaDynamicProxy)的invoke()方法,在invoke()方法里面,我们实现了我的代理逻辑。
我们这里这个Demo的大致UML图如下:
参考:http://www.cnblogs.com/cruze/p/3819761.html 
1.3 CGLib动态代理 
鉴于Java动态代理的限制,我们有需要代理没有任何实现接口的类的时候,可以考虑使用CGLib。CGLib的全称是Code Generate Library。CGLib的使用使用十分广泛,我们这里要讲的Spring AOP,以及EasyMock等。
同样先上Demo代码,我们只需要实现MethodInterceptor接口:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
/**
  * @author xiaobaoqiu  Date: 16-3-10 Time: 下午7:15
  */
 public class CglibDynamicProxy implements MethodInterceptor {
 
     /**
      * 动态生成代理类
      */
     public Object generateProxy(Class cls) {
         Enhancer enhancer = new Enhancer();
         enhancer.setCallback(this);
 //        enhancer.setCallbackFilter(); //filter
         enhancer.setSuperclass(cls);
         return enhancer.create(); // Enhancer也包含带参数的create方法
     }
 
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
         doSomethingBefore();
 
         Object result = proxy.invokeSuper(obj, args);
 
         doSomethingAfter();
 
         return result;
     }
 
     private void doSomethingBefore() {
         System.out.println("CglibDynamicProxy: Before...");
     }
 
     private void doSomethingAfter() {
         System.out.println("CglibDynamicProxy: After...");
     }
 }
 
 //使用
 public static void main(String[] args) {
         CglibDynamicProxy proxy = new CglibDynamicProxy();
         //注意: 原始类的instance不需要存在,只需要Class类型
 
         //用接口IHello接, 或者 HelloImpl 接
         IHello helloAProxy = (IHello)proxy.generateProxy(HelloImpl.class);
         helloAProxy.hello();
 
         System.out.println("-------------------------------------------------");
 
         //用接口IHello接, 或者 HelloWithLogImpl 接
         IHello helloBProxy = (IHello)proxy.generateProxy(HelloWithLogImpl.class);
         helloBProxy.hello();
 
         System.out.println("-------------------------------------------------");
 
         //代理没有实现任何interface的类
         HelloWithoutInterface helloCProxy = (HelloWithoutInterface)proxy.generateProxy(HelloWithoutInterface.class);
         helloCProxy.hello();
 } 
 
同样我们debug一下,得到的信息如下,同样生成了代理类,类名称为proxy.sample.HelloImpl$$EnhancerByCGLIB$$b46b6f06,这个稀奇古怪的类名我们后面会分析:
下面还是尝试分析CGLib动态代理的原理。默认情况下生成的代理class文件只存储在内存中,我们可以在代码中设置一个环境变量:
1 
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/xiaobaoqiu/cglib_proxy"); 
 
之后我们在目标目录下得到很多的class,其中的proxy目录包含了生成的class文件。我们发现一大堆的class文件,类名都是稀奇古怪:
1 
2 
3 
4 
5 
xiaobaoqiu@xiaobaoqiu:~/cglib_proxy/proxy/javaProxy$ ll
 -rw-rw-r-- 1 xiaobaoqiu xiaobaoqiu 2227  3月 21 18:38 HelloWithoutInterface$$EnhancerByCGLIB$$7d786e36.class
 -rw-rw-r-- 1 xiaobaoqiu xiaobaoqiu 5555  3月 21 18:38 HelloWithoutInterface$$EnhancerByCGLIB$$e4e0e0f1.class
 -rw-rw-r-- 1 xiaobaoqiu xiaobaoqiu 7744  3月 21 18:38 HelloWithoutInterface$$EnhancerByCGLIB$$e4e0e0f1$$FastClassByCGLIB$$814877d5.class
 -rw-rw-r-- 1 xiaobaoqiu xiaobaoqiu 2673  3月 21 18:45 HelloWithoutInterface$$FastClassByCGLIB$$32a767a1.class 
 
我们先看看class文件的生成策略。每个Class Generator(比如这里的Enhancer)都继承自AbstractClassGenerator(实现接口ClassGenerator,这个接口只有一个generateClass的方法),需要实现其generateClass()方法。generateClassName()方法用来生成Class名称:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
private String generateClassName(Predicate nameTestPredicate) {
         return namingPolicy.getClassName(namePrefix, source.name, key, nameTestPredicate);
 }
 
 //namingPolicy的默认实现NamingPolicy
 public String getClassName(String prefix, String source, Object key, Predicate names) {
   //prefix为被代理类的路径,
         String base =
             prefix + "$$" +                       //prefix为被代理类的路径
             source.substring(source.lastIndexOf('.') + 1) +       //获取生成代理类的类,比如我们这里的Enhancer
             getTag() + "$$" +                     //getTag()默认为ByCGLIB
             Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());   //hashcode
         String attempt = base;
         int index = 2;
         while (names.evaluate(attempt))       //如果有重复,则再在后面加上下标,小标从2开始
             attempt = base + "_" + index++;
         return attempt;
 } 
 
下面正式进入class文件的生成原理分析,还是从源代码入手,enhancer.create()最终进入AbstractClassGenerator.create()方法,我们发现最终return的Object是从内部变量obj得来,因此,我们看看ClassLoaderData的生成逻辑:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
protected Object create(Object key) {
             ClassLoader loader = getClassLoader();
             Map<ClassLoader, ClassLoaderData> cache = CACHE;
             ClassLoaderData data = cache.get(loader);
             if (data == null) {
                 synchronized (AbstractClassGenerator.class) {
                     data = cache.get(loader);
                     if (data == null) {
                         Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
                         data = new ClassLoaderData(classLoader);
                         newCache.put(classLoader, data);
                         CACHE = newCache;
                     }
                 }
             }
             this.key = key;
             Object obj = data.get(this);
             if (obj instanceof Class) {
                 return firstInstance((Class) obj);
             }
             return nextInstance(obj);
 }
 
 public ClassLoaderData(ClassLoader classLoader) {
             this.classLoader = new WeakReference<ClassLoader>(classLoader);
             Function<AbstractClassGenerator, Object> load =
                     new Function<AbstractClassGenerator, Object>() {
                         public Object apply(AbstractClassGenerator gen) {
                             Class klass = gen.generate(ClassLoaderData.this); //生成class的关键代码
                             return gen.wrapCachedClass(klass);
                         }
                     };
             generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
 } 
 
因此我们将目光转到generate()中:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
//Enhancer的generate()方法
 protected Class generate(ClassLoaderData data) {
         validate();
         if (superclass != null) {
             setNamePrefix(superclass.getName());
         } else if (interfaces != null) {
             setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
         }
         return super.generate(data);  //父类AbstractClassGenerator
 }
 // AbstractClassGenerator的generate()方法
 protected Class generate(ClassLoaderData data) {
             //...
             ClassLoader classLoader = data.getClassLoader();
             this.setClassName(generateClassName(data.getUniqueNamePredicate()));  //代理类的类名称的生成逻辑
             //...
             byte[] b = strategy.generate(this);       //生成策略,默认实现DefaultGeneratorStrategy,生成class文件的字节码
             String className = ClassNameReader.getClassName(new ClassReader(b));
             ProtectionDomain protectionDomain = getProtectionDomain();
             synchronized (classLoader) { // just in case
                 if (protectionDomain == null) {
                     gen = ReflectUtils.defineClass(className, b, classLoader);
                 } else {
                     gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
                 }
             }
             return gen;
             ...//异常处理
 }
 
 //DefaultGeneratorStrategy的generate()方法
 public byte[] generate(ClassGenerator cg) throws Exception {
         DebuggingClassWriter cw = getClassVisitor();
         transform(cg).generateClass(cw);      //这里调用最终的generateClass()逻辑,Visitor模式
         return transform(cw.toByteArray());   //通过Visitor得到最后的字节码
 } 
 
所以最终的调用是Enhancer的generateClass()调用。这代码好晦涩,感觉和JVM加载字节码相关。
看一下CGLib生成的class文件,这个代理类继承了我们的被代理类并且实现了Factory类,类定义如下:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
public class HelloWithoutInterface$$EnhancerByCGLIB$$e4e0e0f1 extends proxy.javaProxy.HelloWithoutInterface implements net.sf.cglib.proxy.Factory {
     private boolean CGLIB$BOUND;
     public static java.lang.Object CGLIB$FACTORY_DATA;
     private static final java.lang.ThreadLocal CGLIB$THREAD_CALLBACKS;
     private static final net.sf.cglib.proxy.Callback[] CGLIB$STATIC_CALLBACKS;
     private net.sf.cglib.proxy.MethodInterceptor CGLIB$CALLBACK_0;
     private static final java.lang.reflect.Method CGLIB$hello$0$Method;
     private static final net.sf.cglib.proxy.MethodProxy CGLIB$hello$0$Proxy;
     private static final java.lang.Object[] CGLIB$emptyArgs;
     private static final java.lang.reflect.Method CGLIB$equals$1$Method;
     private static final net.sf.cglib.proxy.MethodProxy CGLIB$equals$1$Proxy;
     private static final java.lang.reflect.Method CGLIB$toString$2$Method;
     private static final net.sf.cglib.proxy.MethodProxy CGLIB$toString$2$Proxy;
     private static final java.lang.reflect.Method CGLIB$hashCode$3$Method;
     private static final net.sf.cglib.proxy.MethodProxy CGLIB$hashCode$3$Proxy;
     private static final java.lang.reflect.Method CGLIB$clone$4$Method;
     private static final net.sf.cglib.proxy.MethodProxy CGLIB$clone$4$Proxy;
 
     static void CGLIB$STATICHOOK1() { /* compiled code */ }
 
     final void CGLIB$hello$0() { /* compiled code */ }    //代理的方法
 
     public final void hello() { /* compiled code */ } //代理的方法
 
     final boolean CGLIB$equals$1(java.lang.Object o) { /* compiled code */ }
 
     public final boolean equals(java.lang.Object o) { /* compiled code */ }
 
     final java.lang.String CGLIB$toString$2() { /* compiled code */ }
 
     public final java.lang.String toString() { /* compiled code */ }
 
     final int CGLIB$hashCode$3() { /* compiled code */ }
 
     public final int hashCode() { /* compiled code */ }
 
     final java.lang.Object CGLIB$clone$4() throws java.lang.CloneNotSupportedException { /* compiled code */ }
 
     protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { /* compiled code */ }
 
     public static net.sf.cglib.proxy.MethodProxy CGLIB$findMethodProxy(net.sf.cglib.core.Signature signature) { /* compiled code */ }
 
     public HelloWithoutInterface$$EnhancerByCGLIB$$e4e0e0f1() { /* compiled code */ }
 
     public static void CGLIB$SET_THREAD_CALLBACKS(net.sf.cglib.proxy.Callback[] callbacks) { /* compiled code */ }
 
     public static void CGLIB$SET_STATIC_CALLBACKS(net.sf.cglib.proxy.Callback[] callbacks) { /* compiled code */ }
 
     private static final void CGLIB$BIND_CALLBACKS(java.lang.Object o) { /* compiled code */ }
 
     public java.lang.Object newInstance(net.sf.cglib.proxy.Callback[] callbacks) { /* compiled code */ }
 
     public java.lang.Object newInstance(net.sf.cglib.proxy.Callback callback) { /* compiled code */ }
 
     public java.lang.Object newInstance(java.lang.Class[] classes, java.lang.Object[] objects, net.sf.cglib.proxy.Callback[] callbacks) { /* compiled code */ }
 
     public net.sf.cglib.proxy.Callback getCallback(int i) { /* compiled code */ }
 
     public void setCallback(int i, net.sf.cglib.proxy.Callback callback) { /* compiled code */ }
 
     public net.sf.cglib.proxy.Callback[] getCallbacks() { /* compiled code */ }
 
     public void setCallbacks(net.sf.cglib.proxy.Callback[] callbacks) { /* compiled code */ }
 } 
 
注意,我们生成的动态代理包含两个hello()相关的方法。我们可以使用javap获取其字节码,我们发现和我们被代理者同名的hello()方法是带代理逻辑的,而CGLIB$hello$0()这个则是原始被代理者的直接调用(不包含代理逻辑):
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
xiaobaoqiu@xiaobaoqiu:~/cglib_proxy/proxy/javaProxy$ javap -c HelloWithoutInterface\$\$EnhancerByCGLIB\$\$e4e0e0f1.class
 ...
   final void CGLIB$hello$0();
     Code:
        0: aload_0
        1: invokespecial #36                 // Method proxy/javaProxy/HelloWithoutInterface.hello:()V
        4: return
 
   public final void hello();
     Code:
        0: aload_0
        1: getfield      #38                 // Field CGLIB$CALLBACK_0:Lnet/sf/cglib/proxy/MethodInterceptor;
        4: dup
        5: ifnonnull     17
        8: pop
        9: aload_0
       10: invokestatic  #42                 // Method CGLIB$BIND_CALLBACKS:(Ljava/lang/Object;)V
       13: aload_0
       14: getfield      #38                 // Field CGLIB$CALLBACK_0:Lnet/sf/cglib/proxy/MethodInterceptor;
       17: dup
       18: ifnull        37
       21: aload_0
       22: getstatic     #44                 // Field CGLIB$hello$0$Method:Ljava/lang/reflect/Method;
       25: getstatic     #46                 // Field CGLIB$emptyArgs:[Ljava/lang/Object;
       28: getstatic     #48                 // Field CGLIB$hello$0$Proxy:Lnet/sf/cglib/proxy/MethodProxy;
       31: invokeinterface #54,  5           // InterfaceMethod net/sf/cglib/proxy/MethodInterceptor.intercept:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Lnet/sf/cglib/proxy/MethodProxy;)Ljava/lang/Object;
       36: return
       37: aload_0
       38: invokespecial #36                 // Method proxy/javaProxy/HelloWithoutInterface.hello:()V
       41: return
 ... 
 
遗留问题:
(1).为什么一个类会生成多个代理类,各个代理类都是什么用处;
CGLib代理同样存在限制:
(1).private方法无法代理;
(2).final方法无法代理;
 
private方法和final方法看代理类的字节码会发现,代理类不会这些重写函数(子类没法重写),因此会自动调用父类的。
参考:
cglib源码分析(四):cglib 动态代理原理分析 
CGLib: The Missing Manual 
#1.4 Java动态代理 VS CGLib动态代理 
简单总结对比一下两种动态代理:
代理  
 没有实现interface的类  
 protected方法  
 private方法  
 final类  
 final方法  
 构造函数private的类  
 
 
Java动态代理  
 不支持  
 不支持  
 不支持  
支持  
 支持  
 支持  
 
CGLib动态代理  
 支持  
 支持   
 不支持  
不支持  
 不支持  
 不支持  
 
 
关于CGLib对protected方法的支持,可以在生成的代理类中看到.
1 
2 
3 
4 
CGLib报错信息:
 final类: Cannot subclass final class proxy.javaProxy.HelloWithFinal
 构造方法私有的类: No visible constructors in class proxy.javaProxy.HelloWithoutConstructor
 final方法: 不报错,但没有代理逻辑 
 
在性能方面,通常认为Java动态代理生成代理类比CGLib生成代理类快,但是CGLib的代理类运行期性能会优于Java动态代理的代理类。不过通常性能都不是问题,如果确实很关心性能,建议直接使用ASM。
参考:
Why do you think CGLib proxies are faster than JDK Proxies? 
Implement Your Own Proxy-Based AOP Framework Blog 
BeanDefinitionParserDelegate
AnnotationDrivenBeanDefinitionParser
参考:
Spring加载资源分析:http://www.blogjava.net/heavensay/archive/2013/10/28/405699.html 
事务的坑
http://www.ibm.com/developerworks/library/j-ts1/ 
代理实现选择器:
AdviceMode
TransactionManagementConfigurationSelector
声明事务切面实现:
TransactionInterceptor
事务实现
Connection关闭自动提交
ConnectionHolder来保持Connection
参考:
http://openwares.net/java/spring_mybatis_transaction.html 
http://my.oschina.net/guanzhenxing/blog/214228 
http://www.mybatis.org/spring/zh/transactions.html 
http://tracylihui.github.io/2015/07/28/spring/Spring%E5%A3%B0%E6%98%8E%E5%BC%8F%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86/ 
http://www.cnblogs.com/davenkin/archive/2013/02/16/java-tranaction-1.html 
http://www.importnew.com/12300.html 
详细介绍Spring事务管理: http://developer.51cto.com/art/200906/129854.htm 
spring事务原理1-事务的抽象: http://sqtds.github.io/2014/06/09/2014/spring-tx1/ 
Spring官方文档Transaction Management: http://docs.spring.io/autorepo/docs/spring/3.2.x/spring-framework-reference/html/transaction.html 
Spring官方文档Aspect Oriented Programming with Spring: http://docs.spring.io/spring/docs/3.0.x/reference/aop.html 
StackOverFlow Spring - @Transactional - What happens in background?: http://stackoverflow.com/questions/1099025/spring-transactional-what-happens-in-background 
Transaction strategies: Understanding transaction pitfalls: http://www.ibm.com/developerworks/library/j-ts1/ 
Annotation-based Transactions in Spring: http://springinpractice.com/2008/03/18/annotation-based-transactions-in-spring 
Design principle behind Transaction framework with Spring 3: http://stackoverflow.com/questions/11789857/design-principle-behind-transaction-framework-with-spring-3 
Chapter 6. 使用Spring进行面向切面编程(AOP): http://shouce.jb51.net/spring/aop.html 
wiki: http://wiki.corp.qunar.com/display/~yushen.ma/Spring+3.x-JDBC+Transaction 
spring事务: http://wiki.corp.qunar.com/pages/viewpage.action?pageId=52084161 
spring 事务: http://wiki.corp.qunar.com/pages/viewpage.action?pageId=93338632 
aspectj事务: http://wiki.corp.qunar.com/pages/viewpage.action?pageId=92656954 
Demo:
编程事务: http://www.tutorialspoint.com/spring/programmatic_management.htm 
声明事务: http://www.tutorialspoint.com/spring/declarative_management.htm 
@Transactional注解工作原理:http://blog.csdn.net/dslztx/article/details/46636079 
分布式事务系列(1.2)Spring的事务体系: https://yq.aliyun.com/articles/39046 
spring transaction源码分析–事务架构:http://www.cnblogs.com/davidwang456/p/4309038.html 
http://blog.csdn.net/szwangdf/article/details/41516239 
AopProxy
DefaultAopProxyFactory