设计模式(十五):代理模式

1.定义

设计模式(十五):代理模式_第1张图片
优点
设计模式(十五):代理模式_第2张图片
缺点
设计模式(十五):代理模式_第3张图片
spring的动态代理
设计模式(十五):代理模式_第4张图片

2. 静态代理

物品po
设计模式(十五):代理模式_第5张图片
dao接口
设计模式(十五):代理模式_第6张图片
dao实现类
设计模式(十五):代理模式_第7张图片
service接口
设计模式(十五):代理模式_第8张图片
service实现类
设计模式(十五):代理模式_第9张图片
配置多数据源
设计模式(十五):代理模式_第10张图片
动态代理增强save方法
设计模式(十五):代理模式_第11张图片
测试
设计模式(十五):代理模式_第12张图片

3. 动态代理

动态代理

public class OrderServiceDynamicProxy implements InvocationHandler {

    private Object target;

    // 传入需要代理的类
    public OrderServiceDynamicProxy(Object target) {
        this.target = target;
    }

    /**
     * 增强insert方法
     * @return
     */
    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);// 通过Method.invoke来调用反射对象的方法,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+"】处理数据");

        //todo 设置dataSource;
        DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter));
    }

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

测试:
设计模式(十五):代理模式_第13张图片
Proxy.newProxyInstance()通过动态代理生成一个class实例的源码。

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);
		// 克隆接口
        final Class<?>[] intfs = interfaces.clone();
        // 安全检查,查看是否可以代理
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        Class<?> cl = getProxyClass0(loader, intfs);//获取class

        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

			// 通过class获取构造函数
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            // 如果构造函数是私有函数,那么修改权限
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);// 权限设置为共有权限
                        return null;
                    }
                });
            }
			// 通过构造函数实例化一个新的类
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

源码:https://github.com/LUK-qianliu/design_pattern_in_all

你可能感兴趣的:(设计模式)