设计模式---代理模式

定义:
为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介的作用
结构型
适用场景:
保护对象
增强目标对象
优点:
代理模式能将代理对象与真实被调用的目标对象分离
一定程度上降低了系统的耦合度,扩展性好
保护目标对象
增强目标对象
缺点:
代理模式会造成系统设计中类的数目增加
在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
增加系统的复杂度

扩张:
静态代理
动态代理
CGLib代理
Spring代理选择:
当Bean有实现接口时,Spring就会用JDK动态代理
当Bean有没有实现接口时,Spring就会用CGLib动态代理
可以强制使用CGLib
在spring配置中加入 <aop:aspectj-autoproxy proxy-target-class=“true”/>
参考资料:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html

代理速度对比:
CGLib与JDK动态代理对比:万次执行下,JDK7、JDK8的JDK动态代理比CGLib快20%左右。

相关设计模式:
代理模式和装饰者模式
代理模式和适配器模式

Coding

静态代理:

//DTO
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
public interface IOrderDao {

    int insert(Order order);

}
//Dao的实现
public class IOrderDaoImpl implements IOrderDao {
    @Override
    public int insert(Order order) {
        System.out.println("Dao层添加order成功");
        return 1;
    }
}
//Service
public interface IOrderService {

    int saveOrder(Order order);

}
//Service的实现
public class IOrderServiceImpl implements IOrderService{

    private IOrderDao iOrderDao;

    @Override
    public int saveOrder(Order order) {
        iOrderDao = new IOrderDaoImpl();
        System.out.println("Service层调用Dao层添加Order");
        return iOrderDao.insert(order);
    }
}
//代理类
public class OrderServiceStaticProxy {

    private IOrderService iOrderService;

    public int saveOrder(Order order) {
        beforeMethod();
        iOrderService = new IOrderServiceImpl();
        Integer userId = order.getUserId();
        Integer dbRouter = userId % 2;
        System.out.println("静态代理分配到【db"+dbRouter+"】数据处理");

        DataSourceContextHolder.setDBType(String.valueOf("db"+dbRouter));

        int i = iOrderService.saveOrder(order);
        afterMethod();
        return i;
    }

    private void beforeMethod() {
        System.out.println("静态代理 before code");
    }

    private void afterMethod() {
        System.out.println("静态代理 after code");
    }

}

//多数据源选择器
public class DataSourceContextHolder {

    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();


    public static void setDBType(String dbType) {
        CONTEXT_HOLDER.set(dbType);
    }

    public static String getDBType() {
        return CONTEXT_HOLDER.get();
    }

    public static void clearDBType() {
        CONTEXT_HOLDER.remove();
    }
}
//多数据源的实现类
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDBType();
    }

//    <!--多数据源配置 parent指向上面的配置数据库的连接池abstractDataSource 这里配置了两个数据源-->
//    <bean id="dataSource1" parent="abstractDataSource">
//        <property name="url" value="${jdbc_url}" />
//        <property name="username" value="${jdbc_user}" />
//        <property name="password" value="${jdbc_password}" />
//    </bean>
//    <bean id="dataSource2" parent="abstractDataSource">
//        <property name="url" value="${jdbc_url_s}" />
//        <property name="username" value="${jdbc_user_s}" />
//        <property name="password" value="${jdbc_password_s}" />
//    </bean>
//
//    <!-- 在RoutingDataSource类中读取 当前的返回值 并匹配key值 选择你的数据库源-->
//    <bean id="dataSource" class="com.alex.dao.RoutingDataSource">
//        <property name="targetDataSources">
//            <map key-type="java.lang.String">
//                <entry key="dataSource1" value-ref="dataSource1"></entry>
//                <entry key="dataSource2" value-ref="dataSource2"></entry>
//            </map>
//        </property>
//        <property name="defaultTargetDataSource" ref="dataSource1"></property>
//    </bean>
//
//    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
//        <!-- 数据源 -->
//        <property name="dataSource" ref="dataSource"></property>
//        <!-- 别名 -->
//        <property name="typeAliasesPackage" value="com.alex.entity"></property>
//        <!-- sql映射文件路径 -->
//        <property name="mapperLocations" value="classpath*:mapping/*Mapper.xml"></property>
//    </bean>
}

public class Test {

    public static void main(String[] args) {
        Order order = new Order();
        order.setUserId(2);
        OrderServiceStaticProxy orderServiceStaticProxy = new OrderServiceStaticProxy();
        orderServiceStaticProxy.saveOrder(order);
    }

}
静态代理 before code
静态代理分配到【db0】数据处理
Service层调用Dao层添加Order
Dao层添加order成功
静态代理 after code

动态代理:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值