JDK自带方法
首先介绍一下最核心的一个接口和一个方法:
首先是java.lang.reflect包里的InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
我们对于被代理的类的操作都会由该接口中的invoke方法实现,其中的参数的含义分别是:
- proxy:被代理的类的实例
- method:调用被代理的类的方法
- args:该方法需要的参数
使用方法首先是需要实现该接口,并且我们可以在invoke方法中调用被代理类的方法并获得返回值,自然也可以在调用该方法的前后去做一些额外的事情,从而实现动态代理,下面的例子会详细写到。
另外一个很重要的静态方法是java.lang.reflect包中的Proxy类的newProxyInstance方法:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
其中的参数含义如下:
- loader:被代理的类的类加载器
- interfaces:被代理类的接口数组
- invocationHandler:就是刚刚介绍的调用处理器类的对象实例
该方法会返回一个被修改过的类的实例,从而可以自由的调用该实例的方法。下面是一个实际例子。
接口:
public interface Person {
void show();
void dance();
}
被代理类:
public class User implements Person, A {
private int id;
private String name;
private String password;
public void show() {
System.out.println("User show______");
}
public void dance() {
System.out.println("dance____");
}
}
生成代理:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyJdkAgent {
static class MyHandler implements InvocationHandler {
private Object proxy;
public MyHandler(Object proxy) {
this.proxy = proxy;
}
/**
*
* @param proxy 被代理类实例
* @param method 调用被代理的类的方法
* @param args 该方法所需要的参数
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("hehe");
Object res = method.invoke(this.proxy, args);
System.out.println("haha");
return res;
}
}
/**
*
* @param beProxied 被代理类
* @param interfaces 被代理类的接口数组
* @param proxy 被代理类的实例
* @return
*/
public static Object getAgent(Class beProxied, Class[] interfaces, Object proxy) {
/**
* 参数分别是(被代理类加载器,被代理类接口数组,处理器类的对象)
*/
return Proxy.newProxyInstance(beProxied.getClassLoader(), interfaces, new MyHandler(proxy));
}
}
测试:
Person person = (Person) MyJdkAgent.getAgent(User.class, new Class[]{Person.class}, new User());
person.dance();
结果:
hehe
dance____
haha
CGLIB动态代理
被代理类:
public class Car {
private int id;
private User owner;
public void display() {
System.out.println("dididi....");
}
}
生成代理对象类:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyCglibAgent implements MethodInterceptor {
private Object proxy;
/**
*
* @param proxy 被代理类
* @return 代理对象
*/
public Object getInstance(Object proxy) {
this.proxy = proxy;
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(this.proxy.getClass());
// 设置enhancer回调对象
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
/**
*
* @param o 生成的代理对象
* @param method 被代理对象方法
* @param objects 方法参数
* @param methodProxy 代理方法
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before__________");
Object ret = methodProxy.invokeSuper(o, objects);
System.out.println("after____________");
return ret;
}
}
测试:
MyCglibAgent myCglibAgent = new MyCglibAgent();
Car car = (Car) myCglibAgent.getInstance(new Car());
car.display();
结果:
before__________
dididi....
after____________