动态代理
动态代理和静态代理的角色一样。
动态代理的代理类是动态生成的,不是我们直接写好的。
1.动态代理可以分为?
1.1基于接口的动态代理
其中最经典的:JDK动态代理
1.2基于类的动态代理
其中最经典的:CGLIB动态代理
除了以上这些现在使用较多的还有:java字节码实现:javasist
需要了解两个类:Proxy(代理类) 、InvocationHandler(调用处理程序)
2.InvocationHandler
InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口.
每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。
3.Proxy
Proxy类就是用来创建一个代理对象的类,它提供了很多方法,但是我们最常用的是newProxyInstance方法。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
这个方法的作用就是创建一个代理类对象,它接收三个参数,我们来看下几个参数的含义:
(1)loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载
(2)interfaces:一个interface对象数组,表示我们将要给我们的代理对象提供一组什么样的接口,如果我们提供了这样一个接口对象数组,那么也就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。
(3)h:一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。
4.代码实现
//用这个类动态生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理接口
private Object target;
public void setTarget(Object target){
this.target=target;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance
(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this );
}
//处理代理实例,并生返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
//动态代理的本质,就是使用反射机制实现
Object result = method.invoke(target, args);
return result;
}
private void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
public class Client {
public static void main(String[] args) {
//真实角色一定要存在的
UserServiceImpl userService = new UserServiceImpl();
//代理角色,不存在
ProxyInvocationHandler pih=new ProxyInvocationHandler();
//设置要代理的对象
pih.setTarget(userService);
//生成动态代理类
User proxy = (User) pih.getProxy();
proxy.add();
}
}