一、静态代理
代理模式(Proxy Pattern)是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。是一种AOP编程思想。
下面,我们以购买火车票为例,我们可以通过火车站去买票,当一些人不方便时候,可能会通过代售点买票,那么代售点其实可以理解为火车站的代理类,只不过代售点提供了火车站的服务,当然也会收取一定的服务费。
代码如下:
public class hook {
/**
* 售票服务接口
*/
public interface TicketService {
//售票
public void sellTicket();
}
/**
* 售票服务接口实现类,车站
*/
public static class Station implements TicketService {
@Override
public void sellTicket() {
System.out.println("\n\t售票.....\n");
}
}
/**
* 车票代售点
*
*/
public static class StationProxy implements TicketService {
private final Station station;
public StationProxy(Station station){
this.station = station;
}
@Override
public void sellTicket() {
// 1.做真正业务前,提示信息
System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
// 2.调用真实业务逻辑
station.sellTicket();
// 3.后处理 println
System.out.println("××××欢迎您的光临,再见!××××\n");
}
}
public static void main(String[] args) {
Station changchun = new Station();
StationProxy proxy = new StationProxy(changchun);
proxy.sellTicket();
}
}
通过以上的代码,还是很容易理解静态代理了,通过代理类去控制实体类的行为,并可以灵活加上之自己的行为~
二、动态代理
在Java中,动态代理是通过InvocationHandler接口,重写invoke函数实现的。
还是以火车站售票为例,
代码如下:
package com.tiancity.dom.lib;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class dynamic {
/**
* 售票服务接口
*/
public interface TicketService {
//售票
public void sellTicket();
}
/**
* 售票服务接口实现类,车站
*/
public static class Station implements TicketService {
@Override
public void sellTicket() {
System.out.println("\n\t售票.....\n");
}
}
/**
* 车票代售点
*
*/
public static class StationProxy implements InvocationHandler {
private final TicketService station;
public StationProxy(TicketService station){
this.station = station;
}
//com.sun.proxy.$Proxy0 cannot be cast to
//getInterfaces 获取的是接口,不是类,所以要用TicketService
public Object getProxy(){
return (Object) Proxy.newProxyInstance(this.getClass().getClassLoader(),
station.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if(method.getName().equals("sellTicket")){
// 1.做真正业务前,提示信息
System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
// 2.调用真实业务逻辑
result=method.invoke(station, args);
// 3.后处理 println
System.out.println("××××欢迎您的光临,再见!××××\n");
}
return result;
}
}
public static void main(String[] args) {
TicketService dalian = new Station();
StationProxy proxy = new StationProxy(dalian);
TicketService p = (TicketService) proxy.getProxy();
p.sellTicket();
}
}
三、总结
代理模式可以在不修改真实类代码的情况下,实现对真实类的访问控制、性能优化等功能。Java 中有两种实现代理模式的方法:静态代理和动态代理。静态代理需要在编译之前手动编写代理类,而动态代理可以在运行时动态生成代理类。