定义:为其他对象提供一种代理以控制对这个对象的访问,代理对象起到中介作用,可以屏蔽功能或者增加额外的服务
代理模式分为两种:
静态代理:
public interface Run {
void run();
}
public class DogStaticProxy implements Run{
private Dog dog;
public DogStaticProxy(Dog dog){
this.dog=dog;
}
@Override
public void run() {
System.out.println("穿上鞋子!");
dog.run();
}
public static void main(String[] args) {
DogStaticProxy proxy=new DogStaticProxy(new Dog());
proxy.run();
}
}
public class Dog implements Run{
@Override
public void run() {
System.out.println("小狗在跑");
}
public void otherMethod(){
return ;
}
}
代理类通过实现接口,并且采用组合的方式对接口定义的方法做一些增强。这里可能和装饰器模式很想,但只是结构上相似,他们目的不同,装饰器模式为对象加上行为,而代理控制访问,比如上面otherMethod起到了隐藏的作用,客户端只能调用run方法,而装饰器类则通过基础抽象类来获得原目标的所有行为。
动态代理
虽然为狗的run方法实现了代理,但其他类别的动物呢,如果每个动物都添加一个静态代理,会产生很多类,所以这时候需要动态产生代理,实现对不同类,不同方法进行代理,动态代理是运行时才将类创建出来
java动态代理:
public class RunInvocationHandler implements InvocationHandler {
private Object target;
public RunInvocationHandler(Object target){
this.target=target;
}
/**
*
* @param proxy 被代理对象
* @param method 被代理对象的方法
* @param args 参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("穿上鞋子");
//如果方法有返回值,则return返回的对象。return method.invoke(target,args);
method.invoke(target,args);
return null;
}
public static void main(String[] args) {
Dog dog=new Dog();
Run rn = (Run) Proxy.newProxyInstance(dog.getClass().getClassLoader(),
dog.getClass().getInterfaces(),
new RunInvocationHandler(dog)
);
rn.run();
}
}
在运行时生成class,该class需要实现接口,使用java动态代理需要实现InvocationHandler接口。
cglib代理:
对目标类产生一个子类,拦截所有父类方法的调用
public class CglibProxy implements MethodInterceptor {
private static Enhancer enhancer=new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
//callback为实现MethodIntercetpro的类
enhancer.setCallback(this);
return enhancer.create();
}
/**
*
* @param o 目标类
* @param method 方法
* @param objects 参数
* @param methodProxy 代理类实例
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("穿上鞋子!");
return methodProxy.invokeSuper(o,objects);
}
public static void main(String[] args) {
CglibProxy p=new CglibProxy();
Dog proxy = (Dog) p.getProxy( Dog.class);
proxy.otherMethod();
}
}