- 理解:顾名思义就是代替别人做事情,在Java中就是为其他对象提供一种代理,以控制对这个对象的访问,起到一个中介的作用,就向火车票代售点,房产中介,职介所等这一类的工作,为被代理的对象如火车站,房子的业主,用人单位提供自己本身的卖票,卖房/租房,招聘等工作
- 分类:
- 远程代理:C/S模式
- 虚拟代理:根据需要将消耗资源很大的对象进行延迟创建,在真正需要时进行创建
- 保护代理:控制一个对象的访问权限
- 智能引用代理:提供对象的一些其他代理
- 举例智能引用代理中的静态代理和动态代理
- 静态代理:代理类和目标对象的类在编译期间就被确定下来了,都实现了相同的接口或者继承了同一个类,实现静态代理采用聚合的代码开发方式,便于代理类的功能扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发过程中必定要产生更多的代理
按照实现接口的方式实现静态代理
- 静态代理:代理类和目标对象的类在编译期间就被确定下来了,都实现了相同的接口或者继承了同一个类,实现静态代理采用聚合的代码开发方式,便于代理类的功能扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发过程中必定要产生更多的代理
package com.fgy.delegate;
public interface Ticket {
public abstract void sellTickets();
}
目标对象
package com.fgy.delegate;
public class TrainStation implements Ticket {
@Override
public void sellTickets() {
System.out.println("火车站卖的票!!!!");
}
}
代理对象
package com.fgy.delegate;
public class SalePoint implements Ticket {
TrainStation trainstation;
public SalePoint(TrainStation trainStation) {
this.trainstation = trainStation;
}
@Override
public void sellTickets() {
System.out.println("代售点操作卖票");
trainstation.sellTickets();
System.out.println("代售点卖完票了");
}
}
运行结果
②动态代理:就是在代理类和被代理类中间加了一个InvocationHandler,不指定代理类,让程序动态的创建代理。
③创建一个动态代理要解决的问题
1)如何根据加载到内存中的被代理对象,动态的去创建代理对象
2)如何通过代理类的对象调用接口中的方法时,实现对被代理对象的同名方法的调用
举例:
first:创建一个被代理类实现的接口
public interface Human {
void fly();
void say();
}
sec:创建一个被代理类对象
package com.fgy.delegate;
public class SuperMan implements Human {
@Override
public void fly() {
System.out.println("我是超人,我怕谁!!!!God!!!");
}
@Override
public void say() {
System.out.println("I believe I can fly!!!");
}
}
Third:创建一个实现InvocationHandler接口的类
package com.fgy.delegate;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object obj;//被代理对象
//将被代理对象绑定到
public void bind(Object obj) {
this.obj = obj;
}
//通过代理对象调用接口方法时,就会调用如下的handler
/**
* proxy:被代理对象
* method:被代理对象的方法
* args:方法的参数
*
* Object:方法的返回值
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(obj);
return result;
}
}
用来专门生产代理的类
package com.fgy.delegate;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//返回代理对象
public static Object getProxyInstance(Object obj) {//形参是被代理对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
myInvocationHandler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler);
}
}
测试类:
package com.fgy.delegate;
public class TestDelegate {
public static void main(String[] args) {
//创建被代理对象
SuperMan superMan = new SuperMan();
Object proxy = ProxyFactory.getProxyInstance(superMan);
Human human = (Human) proxy;
human.fly();
human.say();
}
}
测试结果
以上就是动态代理的例子
Cglib动态代理和JDK动态代理的区别:
1. JDK 动态代理只能代理实现了接口的类,没有实现接口的类不能实现动态代理
2. Cglib是针对类来实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用