动态代理步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
4.通过代理调用方法
所谓DynamicProxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然,这个DynamicProxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作
一、使用示例:
1、接口
/**
* 目标对象实现的接口,用JDK来生成代理对象一定要实现一个接口* @author fmr
*/
public interface UserService {
public abstract void add();
}
2、接口实现类
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("进入被代理对象的方法体内...");
}
}
3、代理类
/**
* 动态代理类
* @author fmr
*
*/
public class MyInvocationHandler implements InvocationHandler{
//代理对象--目标对象
private Object target;
/**
* 构造方法
* @param proxy
*/
public MyInvocationHandler(Object target) {
super();
this.target= target;
}
/**
* 执行目标对象的方法
* invoke--调用
* 方法参数:
* proxy -- 代理类对象
* method -- 被代理的方法
* args -- 该方法的参数数组
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("目标方法执行前...");
Object result = method.invoke(target, args);
System.out.println("目标方法执行后...");
return result;
}
/**
* 获取目标对象的代理对象
* 返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明 * 过的方法)
* Proxy -- 动态代理类
*/
public Object getProxy() { //this.getClass().getClassLoader(), 也可以
Object obj = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
target.getClass().getInterfaces(),
this);
return obj;
}
}
4、测试用例
/**
* 动态代理测试
* @author fmr
*
*/
public class TestProxy {
public static void main(String[] args) {
//1.生成目标对象
UserService userService = new UserServiceImpl();
//2.生成代理类对象
MyInvocationHandler invocationHandler = new MyInvocationHandler(userService);
//3、通过代理类生成目标对象的代理对象
UserService user = (UserService) invocationHandler.getProxy();
//4,通过代理对象调用目标对象的目标 方法
user.add();
}
}
二、原理分析:
user.add(); 为什么会调用 MyInvocationHandler 的invoke()方法呢?
因为JDK生成的最终真正的代理类,它继承自Proxy并实现了我们定义的Subject接口,在实现Subject接口方法的内部,
通过反射调用了
InvocationHandlerImpl的invoke方法。
通过分析代码可以看出Java 动态代理,具体有如下四步骤:
- 通过实现 InvocationHandler 接口创建自己的调用处理器;
- 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
- 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
- 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入