本设计模式资料源于慕课网,讲师:Geely 《Java设计模式精讲 Debug方式+内存分析》,本人作为自己手打整理作为学习的归纳总结。
一,模式介绍
1,定义和类型
- 定义:为其他对象提供一种代理,以控制对这个对象的访问
- 代理对象在客户端和目标对象之间起到中介的作用
2,适用场景
- 保护目标对象
- 增强目标对象
3,优点
- 代理模式能将代理对象与真实被调用的目标对象分离
- 一定程度上降低了系统的耦合度,扩展性好
- 保护目标对象
4,缺点
- 代理模式会造成系统设计中类的数目增加
- 在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
- 增加系统的复杂度
5,扩展
- 静态代理
- 动态代理
- CGLib代理
二,代码演示
- 业务场景
这里主要是基本的一套 spring 流程,从实体层到控制层,这个模式类似于 spring 中的 AOP; - 实体层
package com.try1.design.structural.proxy;
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;
}
}
- dao层
package com.try1.design.structural.proxy;
public interface IOrderDao {
int insert(Order order);
}
package com.try1.design.structural.proxy;
public class OrderDaoImpl implements IOrderDao {
@Override
public int insert(Order order) {
System.out.println("Dao层添加order成功!");
return 1;
}
}
- service层
package com.try1.design.structural.proxy;
public interface IOrderService {
int saveOrder(Order order);
}
package com.try1.design.structural.proxy;
public class OrderServiceImpl implements IOrderService {
private IOrderDao iOrderDao;
@Override
public int saveOrder(Order order) {
//代替spring中的注解注入
iOrderDao=new OrderDaoImpl();
System.out.println("service层调用dao层添加order");
return iOrderDao.insert(order);
}
}
- 代理块
package com.try1.design.structural.proxy;
public class OrderServiceStaticProxy {
private IOrderService iOrderService;
public int saveOrder(Order order){
beforeMethod(order);
iOrderService=new OrderServiceImpl();
int result=iOrderService.saveOrder(order);
afterMethod();
return result;
}
private void beforeMethod(Order order){
System.out.println("静态代理 before code");
int userId=order.getUserId();
int dbRouter=userId%2;
System.out.println("静态代理分配到【db"+dbRouter+"】处理数据");
//todo 这里是有一个spring的静态分配类
System.out.println("进行分类");
}
private void afterMethod(){
System.out.println("静态代理 after code");
}
}
- 动态代理
package com.try1.design.structural.proxy.dynamicproxy;
import com.try1.design.structural.proxy.Order;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class OrderServiceDynamicProxy implements InvocationHandler {
private Object target;
public OrderServiceDynamicProxy(Object target){
this.target=target;
}
public Object bind(){
Class 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");
int userId=0;
if (obj instanceof Order){
Order order=(Order)obj;
userId=order.getUserId();
int dbRouter=userId%2;
System.out.println("动态代理分配到【db"+dbRouter+"】处理数据");
//todo 这里是有一个spring的静态分配类
System.out.println("进行分类");
}
}
private void afterMethod(){
System.out.println("动态代理 after code");
}
}
- 静态代理测试
package com.try1.design.structural.proxy;
public class Test {
public static void main(String[] args) {
Order order=new Order();
order.setUserId(2);
OrderServiceStaticProxy orderServiceStaticProxy=new OrderServiceStaticProxy();
orderServiceStaticProxy.saveOrder(order);
}
}
- 动态代理测试
package com.try1.design.structural.proxy.dynamicproxy;
import com.try1.design.structural.proxy.IOrderService;
import com.try1.design.structural.proxy.Order;
import com.try1.design.structural.proxy.OrderServiceImpl;
public class Test {
public static void main(String[] args) {
Order order=new Order();
order.setUserId(2);
IOrderService orderServiceDynamicProxy= (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind();
orderServiceDynamicProxy.saveOrder(order);
}
}
三,总结
- 代理模式其实就是在具体实现和要实现的对象之间加一个选择实现的类,有点像老板和客户之间的秘书,起到一个中间选择传递的作用
- 静态和动态之间区别在于,中间一个类的判断方式。