java设计模式之代理模式

代理模式(Proxy Pattern)为其他对象(类)提供一种代理,以控制对这个对象(类)的访问。代理对象在客户端和目标对象之间起到中介的作用。这种类型的设计模式属于结构型模式。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

当直接访问对象会遇到一些问题时,例如:有些对象由于一些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),这时直接访问就不是一种好的选择。

代理的思想在实际中也有很多的运用,例如:Windows快捷方式,Spring AOP的实现。

代理模式的应用场景:保护目标对象(控制对目标对象的访问)、增强目标对象

代理模式的优点:

  • 代理模式能将代理对象与真实被调用的目标对象分离
  • 一定程度上降低了系统的耦合度,扩展性好
  • 保护目标对象
  • 增强目标对象

代理模式的缺点:

  • 代理模式会造成系统设计中类的数目增加
  • 在客户端和目标对象间增加一个代理对象,会造成请求处理速度变慢
  • 增加系统的复杂度

相关设计模式:装饰者模式、适配器模式

注意:

  • 适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口
  • 装饰器模式为了增强功能,而代理模式是为了加以控制

代理分为静态代理和动态代理,而动态代理又有两种实现方式:

  • JDK动态代理(无法代理类,只能代理接口)
  • CGLib代理(通过继承,使用时要注意final修饰符)

接下来,我用一个简易下单的方式对代理模式进行实现

  • 静态代理
    步骤一:创建一个实体对象
public class Order {
	private Object orderInfo;
	private Integer userId;
	public Object getOrderInfo() {
		return orderInfo;
	}
	public void setOrderInfo(Object orderInfo) {
		this.orderInfo = orderInfo;
	}
	public Integer getUserId() {
		return userId;
	}
	public void setUserId(Integer userId) {
		this.userId = userId;
	}
}

步骤二:创建一个接口

public interface IOrderService {
	int saveOrder(Order order);
}

步骤三:创建接口的实现类

public class OrderServiceImpl implements IOrderService {

	private IOrderDao orderDao;
	
	@Override
	public int saveOrder(Order order) {
		orderDao = new OrderDaoImpl();
		System.out.println("service层调用dao层方法添加订单");
		return orderDao.insert(order);
	}
}

步骤四:创建dao层接口

public interface IOrderDao {
	int insert(Order order);
}

步骤五:创建dao层接口的实现类

public class OrderDaoImpl implements IOrderDao {

	@Override
	public int insert(Order order) {
		System.out.println("Dao层添加Order成功");
		return 1;
	}

}

JDK静态代理实现之创建静态代理类

  • java.lang.reflect.Proxy:生成动态代理类和对象;
  • java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现
public class OrderServiceStaticProxy {
	private IOrderService iOrderService;
	
	// 对IOrderService接口中的方法进行增强
	public int saveOrder(Order order) {
		beforeMethod(order);
		iOrderService = new OrderServiceImpl();
		afterMethod();
		int result = iOrderService.saveOrder(order);
		return result;
	}
	
	private void beforeMethod(Order order) {
		System.out.println("静态代理 before code");
	}
	private void afterMethod() {
		System.out.println("静态代理 after code");
	}
}

JDK动态代理实现之创建动态代理类

public class OrderServiceDynamicProxy implements InvocationHandler {

	// 目标对象
	private Object target;
	
	public OrderServiceDynamicProxy(Object target) {
		this.target = target;
	}
	
	public Object bind() {
		Class<? extends Object> cls = target.getClass();
		return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object argObject = args[0];
		beforeMethod(argObject);
		Object object = method.invoke(target, args);
		afterMethod();
		return object;
	}
	
	private void beforeMethod(Object obj) {
		System.out.println("动态代理 before code");
	}
	
	private void afterMethod() {
		System.out.println("动态代理 after code");
	}
}

Cglib 动态代理
Cglib 动态代理是针对代理的类, 动态生成一个子类, 然后子类覆盖代理类中的方法, 如果是private或是final类修饰的方法,则不会被重写。

CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。两者没有什么本质的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值