JDK动态代理和CGlib动态代理
JDK动态代理
JDK动态代理是Spring动态代理的默认实现方法。如果我们的类实现了一个接口,那么Spring就会使用这种方法,因为使用JDK动态代理的一个缺陷就是代理的类必须实现接口。
JDK
实现动态代理需要两个组件,首先第一个就是InvocationHandler
接口。我们在使用JDK
的动态代理时,需要编写一个类,去实现这个接口,然后重写invoke
方法,这个方法其实就是我们提供的代理方法。
1 | /** |
然后JDK
动态代理需要使用的第二个组件就是Proxy
这个类,我们可以通过这个类的newProxyInstance
方法,返回一个代理对象。生成的代理类实现了原来那个类的所有接口,并对接口的方法进行了代理,我们通过代理对象调用这些方法时,底层将通过反射,调用我们实现的invoke
方法。
1 | IHello iHello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), // 加载接口的类加载器 |
JDK动态代理的要求:
- 委托类和代理类实现的公共接口
- 实现公共接口的具体委托类
- InvocationHandler接口被Proxy类回调处理,一般实现 InvocationHandler 接口的类具有委托类引用,接口方法 invoke 中添加公共代码并调用委托类的接口方法
- JDK提供生成动态代理类的核心类Proxy
JDK的动态代理,是创建了一个匿名类来继承Proxy类,然后实现了需要被代理的接口。因为Java只能单继承,所以代理类不能通过继承来实现。
CGLib动态代理
若需要代理的类没有实现接口,此时JDK
的动态代理将没有办法使用,于是Spring
会使用CGLib
的动态代理来生成代理对象。
CGLib是基于继承的,如果对应的类无法被继承,或者对应方法无法被重写,那么CGLib也无法生成代理对象。