JDK动态代理
特点
优点:jdk自带,不需导入jar包
缺点:真实对象必须实现接口、利用反射效率不高
实现步骤
①创建处理器:
需实现InvocationHandler接口,实现invoke方法(参数:代理对象,被代理方法,方法参数)
需持有真实对象,在invoke中通过method.invoke进行调用被代理方法
②生成代理对象:
proxy.newProxyInstance()
参数:
反射时需要的类加载器(两个类为同一个加载器)
代理对象实现接口(new Class[]{接口.class})
处理器
例:
具体类ReallObejct实现接口AllObject
①处理器
public class DynamicProObject implements InvocationHandler {
AllObject myObject;
public DynamicProObject() {}
public DynamicProObject(AllObject myObject) {
super();
this.myObject = myObject;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("ago thing");
method.invoke(myObject, args);
System.out.println("after thing");
return null;
}
}
②生成代理对象
public static void main(String[] args) {
AllObject myObject = new ReallObject();
//生成处理器
DynamicProObject handler = new DynamicProObject(myObject);
//生成代理对象
AllObject neProxy = (AllObject)Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(),
new Class[] {AllObject.class},handler);
//测试代理
neProxy.oneThing();
//测试出代理类的父类及接口
System.out.println(neProxy.getClass().getGenericSuperclass());
Type[] allInter = neProxy.getClass().getGenericInterfaces();
for (Type type : allInter) {
System.out.println(type);
}
}
③结果
Ps:这也就是具体类为什么要实现接口的原因:
生成的代理类继承了Proxy类,而Java并不能多继承,使得代理类和具体必须实现一个共同的接口来产生联系
CGLIB动态代理
特点
优点:基于字节码(.class文件)效率高
缺点:第三方jar包(cglib、asm(字节码解析工具包))
实质:给需要代理的类生成一个子类,实现代理方法
实现步骤
①创建处理器:
需实现MethodInterceptor接口,实现intercept方法(参数:子类对象,被代理方法,方法参数,生成的子类代理方法)
调用被代理方法:父类方法.invoke(arg0,arg2)或子类方法.invokeSuper(arg0,arg2)
②生成代理对象(使用Enhancer类的对象):
设置父类:.setSupperclass(被代理类.class)
设置处理器:.setCallback(处理器对象)
生成对象:.create()
例:
①创建处理器
public class DynamicProCGLIB implements MethodInterceptor{
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("ago thing");
arg3.invokeSuper(arg0, arg2);
System.out.println("after thing");
return null;
}
}
②生成代理对象
public static void main(String[] args) {
//进行相关处理
Enhancer hancer = new Enhancer();
hancer.setSuperclass(ReallyCGLIB.class);
hancer.setCallback(new DynamicProCGLIB());
//生成子类对象
ReallyCGLIB eCglib = (ReallyCGLIB)hancer.create();
eCglib.one();
//测试出代理类的父类及接口
System.out.println(eCglib.getClass().getGenericSuperclass());
Type[] allInter = eCglib.getClass().getGenericInterfaces();
for (Type type : allInter) {
System.out.println(type);
}
}
③结果
此处发现CGLIB的实质是创建了具体类的子类,并使其实现cglib动态代理工厂的接口,得以完成代理过程