总所周知,两种通用代理:
jdk动态代理、cglib代理
jdk动态代理 (java.lang.reflect.Proxy java.lang.reflect.InvocationHandler)
需要注意,jdk自带的代理只能为接口创建代理类
方法一
1.调用Proxy.getProxyClass()方法获取代理类的Class对象
2.使用InvocationHandler接口创建代理类的处理器
3.通过代理类和InvocationHandler创建代理对象
4.上面已经创建好代理对象了,接着我们就可以使用代理对象了
Class<xxx接口类> 代理类对象名 = (Class<xxx接口类>) Proxy.getProxyClass(xxx接口.class.getClassLoader(), xxx接口.class);
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwabled {
xxx操作;
return xxx;
}
};
xxx接口类 实例名 = 代理类对象名.getConstructor(InvocationHandler.class).newInstance(invocationHandler);
实例名.x相关方法();
方法二(相对简单)
1.使用InvocationHandler接口创建代理类的处理器
2.使用Proxy类的静态方法newProxyInstance直接创建代理对象
3.使用代理对象
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwabled {
xxx操作;
return xxx;
}
};
xxx接口类 实例名 = (xxx接口类)Proxy.newProxyInstance(xxx接口.class.getClassLoader(), new Class[]{xxx接口.class}, invocationHandler);
实例名.x相关方法();
当然也可以通过继承InvocationHandller来创建通用的代理处理器,在其中的方法返回时实现代理
由于jdk动态代理只能为接口创建代理,使用具有上限,所以cglib是个好选择
CGLib 代理 (Enhancer MethodInterceptor)
cglib是一个强大、高性能的字节码生成库,它用于在运行时扩展Java类和实现接口;本质上它是通过动态的生成一个子类去覆盖所要代理的类(非final修饰的类和方法)。Enhancer可能是CGLIB中最常用的一个类,和jdk中的Proxy不同的是,Enhancer既能够代理普通的class,也能够代理接口。Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)。Enhancer不能够拦截final方法,例如Object.getClass()方法,这是由于Java final方法语义决定的。基于同样的道理,Enhancer也不能对final类进行代理操作。
1.创建Enhancer对象
Enhancer enhancer = new Enhancer();
2.通过setSuperClass来设置父类型,即需要给哪个类创建代理类
enhancer.setSuperclass(被代理的类.class);
3.设置回调,需实现org.springframeword.cglib.proxy.Callback接口,这里演示使用org.springframework.cglib.proxy.MethodInterceptor,是一个继承了Callback接口的接口
(拦截所有方法(MethodInterceptor)、拦截所有方法并返回固定值(FixedValue)、直接放行,不做任何操作(NoOp.INSTANCE)、不同的方法使用不同的拦截器(CallbackFilter))
enhancer.setCallback(new MethodInterceptor() {
/**
* 代理对象方法拦截器
* @param o 代理对象
* @param method 被代理的类的方法,即Service1中的方法
* @param objects 调用方法传递的参数
* @param methodProxy 方法代理对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("调用方法:" + method);
//可以调用MethodProxy的invokeSuper调用被代理类的方法
Object result = methodProxy.invokeSuper(o, objects);
return result;
}
});
4.获取代理对象,调用enhancer.create方法获取代理对象,返回的是Object,需要强转
类 代理对象名 = enhancer.craete();
5.即可使用代理对象进行方法调用;
标签:知识点,Object,xxx,代理,接口,InvocationHandler,动态,方法
From: https://www.cnblogs.com/kris-cbl/p/17109900.html