设计模式(十二)代理模式

一.定义与类型

1.定义:为其他对象提供一种代理,以控制对这个对象的访问

代理对象在客户端和目标对象之间起到中介的作用

2.类型:结构型

二.适用场景

1.保护目标对象

2.增强目标对象

三.优点

1.代理模式能将代理对象与真实被调用的目标对象分离

2.一定程度上降低了系统的耦合度,扩展性好

3.保护目标对象

4.增强目标对象

四.缺点

1.代理模式会造成系统设计中类的数目增加

2.在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢

3.增加了系统的复杂度

五.扩展

1.静态代理

在代码中显示指定的代理

2.动态代理

只能对实现的接口的类实现代理,并不能针对一个具体的实现类

3.CGLib代理

可以代理类,针对类实现进行代理

六.Spring代理选择

1.当Bean有实现接口时,Spring就会用JDK的动态代理

2.当Bean没有实现接口时,Spring使用CGlib

3.可以强制使用Cglib

      在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

七.代理速度对比

1.万次执行情况下,JDK7和JDK8的动态代理性能要比CGLib大约快20%左右

8.UML

9.j静态代理代码

IOrderDao.java
package com.caomingyu.autotest.proxy;

public interface IOrderDao {
    int insert(Order order);
}
IOrderService
package com.caomingyu.autotest.proxy;

public interface IOrderService {
    int saveOrder(Order order);
}
OrderDaoImpl.java
package com.caomingyu.autotest.proxy;

public class OrderDaoImpl implements IOrderDao {
    public int insert(Order order) {
        System.out.println("Dao层添加Order成功");
        return 1;
    }
}
OrderServiceImpl.java
package com.caomingyu.autotest.proxy;

public class OrderServiceImpl implements IOrderService {
    private IOrderDao iOrderDao;
    public int saveOrder(Order order) {
        iOrderDao = new OrderDaoImpl();
        System.out.println("Service层调用Dao层添加Order");
        return iOrderDao.insert(order);
    }
}
OrderServiceStaticProxy.java
package com.caomingyu.autotest.proxy.staticproxy;

import com.caomingyu.autotest.proxy.IOrderService;
import com.caomingyu.autotest.proxy.Order;
import com.caomingyu.autotest.proxy.OrderServiceImpl;
import com.caomingyu.autotest.proxy.db.DataSourceContextHolder;

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){
        int userId = order.getUserId();
        int dbRouter = userId % 2;
        System.out.println("静态代理分配到 【db" + dbRouter + "】处理数据");
        //设置dataSource
        DataSourceContextHolder.setDBType("db" + String.valueOf(dbRouter));
        System.out.println("静态代理 before code");
    }

    private void afterMethod(){
        System.out.println("静态代理 after code");
    }
}
Test.java
package com.caomingyu.autotest.proxy.staticproxy;

import com.caomingyu.autotest.proxy.Order;

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

10.动态代理代码

只要把OrderServiceStaticProxy.java换成OrderServiceDynamicProxy.java

package com.caomingyu.autotest.proxy.dynamicproxy;

import com.caomingyu.autotest.proxy.Order;
import com.caomingyu.autotest.proxy.db.DataSourceContextHolder;

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);
    }

    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){
        int userId = 0;
        System.out.println("动态代理 before code");
        if (obj instanceof Order){
            Order order = (Order) obj;
            userId = order.getUserId();
        }
        int dbRouter = userId % 2;
        System.out.println("动态代理分配到 【db" + dbRouter + "】处理数据");
        //设置dataSource
        DataSourceContextHolder.setDBType("db" + String.valueOf(dbRouter));
        System.out.println("动态代理 before code");
    }

    private void afterMethod(){
        System.out.println("动态代理 after code");
    }
}
Test.java
package com.caomingyu.autotest.proxy.dynamicproxy;

import com.caomingyu.autotest.proxy.IOrderService;
import com.caomingyu.autotest.proxy.Order;
import com.caomingyu.autotest.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);
    }
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值