一,定义与类型
定义:为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介作用
类型:结构型
二,适用场景
1.保护目标对象
2.增强目标对象
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
三,优点:
1.代理模式能将代理对象与真实被调用的目标对象分离
2.一定程度上降低了系统的耦合度,扩展性好
3.保护目标对象
4.增强目标对象
四,缺点:
1.代理模式会造成系统设计中类的数目增加
2.在客户端和目标对象增加了一个代理对象,造成请求处理速度变慢
3.增加系统的复杂度
五,扩展:
静态代理: 由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了
动态代理: 在程序运行时通过反射机制动态创建的。在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。真正的代理对象由JDK再运行时为我们动态的来创建。
CGlib代理: JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过 字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
Spring代理选择:当有Bean时,Spring用JDK动态代理,没有时,用CGlib
六,代码演练:
1.Order类
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;
}
}
2.IOrderService
public interface IOrderService {
int saveOrder(Order order);
}
3.OrderServiceImpl
public class OrderServiceImpl implements IOrderService {
private IOrderDao iOrderDao;
@Override
public int saveOrder(Order order) {
//spring会自己注入,现在直接new
iOrderDao=new IOrderDaoImpl();
System.out.println("service层调用Dao层添加Order");
return iOrderDao.insert(order);
}
}
- IOrderDao
public interface IOrderDao {
int insert(Order order);
}
5.IOrderDaoImpl
public class IOrderDaoImpl implements IOrderDao {
@Override
public int insert(Order order) {
System.out.println("Dao层添加Order成功");
return 1;
}
}
6.DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDBType();
}
}
7.DataSourceContextHolder
public class DataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT_HOLDER=new ThreadLocal<String>();
public static void setDBType(String dbType){
CONTEXT_HOLDER.set(dbType);
}
public static String getDBType(){
return (String)CONTEXT_HOLDER.get();
}
public static void clearDBType(){
CONTEXT_HOLDER.remove();
}
}
8.OrderServiceStaticProxy
public class OrderServiceStaticProxy {
private IOrderService iOrderService;
public int saveOrder(Order order){
beforeMethod();
iOrderService =new OrderServiceImpl();
int userId=order.getUserId();
int dbBouter=userId%2;
System.out.println("静态代理分配的db:"+dbBouter+" 处理数据");
DataSourceContextHolder.setDBType(String.valueOf(dbBouter));
afterMethod();
return iOrderService.saveOrder(order);
}
private void beforeMethod(){
System.out.println("静态代理 before code");
}
private void afterMethod(){
System.out.println("静态代理 after code");
}
}
9.Test 类
public class Test {
public static void main(String[] args) {
Order order=new Order();
order.setUserId(1);
OrderServiceStaticProxy orderServiceStaticProxy=new OrderServiceStaticProxy();
orderServiceStaticProxy.saveOrder(order);
}
}