1. 什么是代理
我们不直接访问目标对象,而是访问第三方对象,通过这个对象完成目标对象的功能,类似现实中的房屋中介的作用
2. 为什么要用代理
我们就拿房屋中介的例子来讲
- 保护了房东的隐私
一般我们不需要直接和房东联系,对于房东来讲,最后成功交易的就只有一个,其他的,对他来说都是骚扰,呵呵。 - 交流便利性
中介是专业做这个的,对房屋信息,周边环境,人员支持上都会方便一点,而且可能非常热情 - 额外服务
比如一些和银行贷款,房产交易中心的一些信息同步、沟通等,相关手续的办理等,效率也非常地高
3. 具体实现
代理一般我们分为静态代理和动态代理
静态代理:就是在程序运行之前,代理类.class文件就已经存在
动态代理:就是使用反射机制,程序运行中动态生成的
- 静态代理实现
public class StaticProxyTest {
//售卖房屋抽象
static interface House {
void sale();
}
//被代理对象
static class HouseOwner implements House {
@Override
public void sale() {
// TODO Auto-generated method stub
System.out.println("房东售房");
}
}
//代理对象
static class HouseAgent implements House {
//存放代理对象
private HouseOwner owner;
public HouseAgent(HouseOwner owner) {
this.owner = owner;
}
@Override
public void sale() {
System.out.println("中介代理售房开始");
//中间使用代理对象的实际业务
owner.sale();
System.out.println("中介代理售房结束");
}
}
public static void main(String[] args) {
//生成中介代理,需要传进一个房东
HouseAgent agent = new HouseAgent(new HouseOwner());
//增强的售卖功能
agent.sale();
}
}
//中介代理售房开始
//房东售房
//中介代理售房结束
静态代理总结:
- 优点:符合开闭原则,在添加代理方法时,不需要修改原来的方法
- 缺点:维护起来比较麻烦,每一个代理服务,可能需要单独创建一个类,然后如果原方法发生变化时,代码方法也需要相应的调整,这时我们的动态代理就派上用场了。
- 动态代理实现
动态代理基本有两种:JDK自带的动态代理和Cglib动态代理。
1)JDK自带的动态代理
public class DynamicProxyTest1 {
// 售卖房屋抽象
static interface House {
void sale();
}
// 被代理对象
static class HouseOwner implements House {
@Override
public void sale() {
// TODO Auto-generated method stub
System.out.println("房东售房");
}
}
// 动态代理
static class HouseDynamicProxy implements InvocationHandler {
private Object obj;
public HouseDynamicProxy(final Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("中介代理售房开始");
Object result = method.invoke(obj, args);
System.out.println("中介代理售房结束");
return result;
}
}
public static void main(String[] args) {
House house = new HouseOwner();
//生成动态代理对象
House houseProxy = (House)Proxy.newProxyInstance(House.class.getClassLoader(), new Class[] {House.class},
new HouseDynamicProxy(house));
//执行代理方法
houseProxy.sale();
}
}
//中介代理售房开始
//房东售房
//中介代理售房结束
2)Cglib代理
JDK自带的代理,需要被代理类实现相关的接口,而如果没有实现接口,该怎么办呢,Cglib就派上用场了。
我们先来看它的实现方法:
public class CglibDynamicProxyTest {
// 售卖房屋抽象
static interface House {
void sale();
}
// 被代理对象
static class HouseOwner implements House {
@Override
public void sale() {
System.out.println("房东售房");
}
}
static class HouseCglibProxy implements MethodInterceptor {
private Object target;
HouseCglibProxy(final Object target){
this.target = target;
}
public Object getInstance(final Object target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("中介代理售房开始");
Object result = method.invoke(target, args);
System.out.println("中介代理售房结束");
return result;
}
}
public static void main(String[] args) {
House house = new HouseOwner();
HouseCglibProxy cglibProxy = new HouseCglibProxy(house);
HouseOwner houseOwner = (HouseOwner)cglibProxy.getInstance(house);
houseOwner.sale();
}
}
//中介代理售房开始
//房东售房
//中介代理售房结束
- 两种动态代理的区别
- JDK动态代理实现代理对象的接口,而Cglib是继承了代理对象
- 他们都是运行期间生成字节码,但Cglib更复杂一些,因此在生成大量对象时,效率要低一点
- Cglib是通过FastClass机制调用,执行效率要比JDk自带的要高一些
具体用哪个代理,相信大家都有自己的选择了! -_-
网友评论