java设计模式之代理模式

代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。在实际生活中,也有代理,例如:房地产中介,明星的经纪人。

代理模式包含如下角色:

ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。

RealSubject:真实主题角色,是实现抽象主题接口的类。

Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

代理模式的实现思路:

1.代理对象和目标对象均实现同一个行为接口。
2.代理类和目标类分别具体实现接口逻辑。
3.在代理类的构造函数中实例化一个目标对象。
4.在代理类中调用目标对象的行为接口。
5.客户端想要调用目标对象的行为接口,只能通过代理类来操作。

代理模式有静态代理和动态代理。

实现动态代理的关键技术是反射。同时,代理模式也是Spring AOP的核心机制之一。

1.静态代理。

静态代理是由程序员编写的代理类,并在程序运行前就编译好的,而不是由程序动态产生代理类,这就是所谓的静态。

/**
 * 抽象主题接口
 */
public interface Manager {
	void doSomething();
}

/**
 * 真实主题对象
 */
public class Admin implements Manager{

	@Override
	public void doSomething() {
		System.out.println("Admin.doSomething()");
	}
}
/**
 * 代理对象
 */
public class ManngerProxy implements Manager{

	private Admin admin;
	
	public ManngerProxy(Admin admin) {
		super();
		this.admin = admin;
	}

	@Override
	public void doSomething() {
		System.out.println("打印日志开始。。。");
		admin.doSomething();
		System.out.println("打印日志结束。。。");
	}
}

/**
 * 客户端测试
 */
public class ClientTest {
	public static void main(String[] args) {
		Admin admin=new Admin();
		ManngerProxy proxy=new ManngerProxy(admin);
		proxy.doSomething();
		
	}
}

测试结果:

打印日志开始。。。
Admin.doSomething()
打印日志结束。。。

由于静态代理需要事先写好代理类,当业务逻辑复杂的时候就会非常麻烦,也非常的不灵活,相比静态代理,动态代理具有更强的灵活性。

2.动态代理

动态代理是指在运行时动态生成代理类。即,代理类的字节码将在运行时生成并载入当前代理的 ClassLoader。

生成动态代理的方法有很多: JDK中自带动态代理, CGlib, javassist等。这些方法各有优缺点。本文主要记录JDK中的动态代理的使用。

/**
 * 抽象主题接口
 */
public interface Moveable {
	void move()throws Exception;
}

/**
 * 真实主题对象
 */
public class Car implements Moveable {

	@Override
	public void move() throws Exception {
		Thread.sleep(new Random().nextInt(1000));
		System.out.println("Car:汽车行驶中。。。");
	}
}

/**
 * 事务处理类
 */
public class TimerHandler implements InvocationHandler {
	private Object target;
	

	public TimerHandler(Object target) {
		super();
		this.target = target;
	}


	/* 参数:
	 * proxy:被代理的对象
	 * method:被代理对象的方法
	 * args:方法的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		long start_time = System.currentTimeMillis();
		System.out.println("汽车开始行驶。。。");
		method.invoke(target, args);
		long end_time = System.currentTimeMillis();
		System.out.println("汽车行驶结束。。。");
		System.out.println("汽车行驶时间:"+(end_time-start_time)+"毫秒");
		return null;
	}

}

/**
 * 客户端测试
 */
public class ClientTest {
	public static void main(String[] args) throws Exception {
		Car car=new Car();
		InvocationHandler h=new TimerHandler(car);
		Class<?> clz = car.getClass();
		/*
		 * Proxy.newProxyInstance()方法的参数:
		 * loader:类加载器
		 * interfaces:实现接口
		 * h:InvocationHandler
		 */
		Moveable m = (Moveable) Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), h);
		m.move();
	}
}

测试结果:

汽车开始行驶。。。
Car:汽车行驶中。。。
汽车行驶结束。。。
汽车行驶时间:456毫秒



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值