初识CGlib动态代理技术
之前在JDK代理技术提到代理设计模式的三要素:
- 有原始类
- 额外的方法
- 和原始类实现相同的方法
对于CGlib也是一样的
1.和JDK代理模式对比
JDK代理模式
例如:
他们都实现了相同的接口,看代理类和原始类的区别,区别在被代理的对象的方法中添加了额外功能。
同时从这个图可以看出代理类和原始类是兄弟关系。
JDK代理是基于接口实现的,也就是说实现JDK必须要实现接口
而CGlib是基于继承关系,例如
如果一个类没有实现接口,那么如何实现动态代理呢?
CGlib提供了解决方案
可以看出CGlib是基于父子关系,至此,也就解答了之前为啥要使用接口接受代理对象的原因。
2.CGlib动态代理技术的实现
由于是基于继承关系,所以不用在代理实现中实现接口,只需要实现原始类即可
原始类
public class UserServiceImplNew implements UserService {
@Override
public void register(User user) {
System.out.println("UserServiceImplNew.register");
}
@Override
public void login(String name, String password) {
System.out.println("UserServiceImplNew.login");
}
}
1.在代理实现中实现原始类
直接new即可
final UserService userService=new UserServiceImplNew();
2.声明增类,以及对对应的方法设置
Enhancer enhancer=new Enhancer();
//和JDK一样,依然需要提供类加载器
enhancer.setClassLoader(userService.getClass().getClassLoader());
//指定类为父类
enhancer.setSuperclass(userService.getClass());
3.实现MethodInterceptor接口
基本等效于InvocationHandler
MethodInterceptor interceptor =new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGlibModle.intercept");
Object ret=method.invoke(userService,objects);
return ret;
}
};
其中的intercept函数和JDK所需要内容是高度一致的
- Object o 返回的对象
- Method method 传入的方法
- Object[] objects 参数列表
- MethodProxy methodProxy 代理的方法
根据代理设计模式的三要素中的和原始类实现相同的方法,使用invoke函数传入实现类和参数列表
注意:有的CGlib版本intercept的第二个参数是args这里是objects,其实都一样
4.把代理类创建出来和使用
enhancer.setCallback(interceptor);
UserService userServiceProxy= (UserService) enhancer.create();
userServiceProxy.register(new User());
userServiceProxy.login("SY","123456");
运行结果:
完整代码:
package org.PoxyModle;
import org.User;
import org.UserService;
import org.UserServiceImplNew;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGlibModle {
public static void main(final String[] args) {
final UserService userService=new UserServiceImplNew();
Enhancer enhancer=new Enhancer();
enhancer.setClassLoader(userService.getClass().getClassLoader());
enhancer.setSuperclass(userService.getClass());
MethodInterceptor interceptor =new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGlibModle.intercept");
Object ret=method.invoke(userService,objects);
return ret;
}
};
enhancer.setCallback(interceptor);
UserService userServiceProxy= (UserService) enhancer.create();
userServiceProxy.register(new User());
userServiceProxy.login("SY","123456");
}
}
大概就是这个流程