代理模式


import java.util.ArrayList;
import java.util.List;

/**
 * 装饰器模式: 侧重于对目标类中核心逻辑的扩展, 依然是以目标类为中心
 * 代理模式  : 侧重于对目标类的访问限制于处理,或者对其添加一些重用性且与 核心业务逻辑无关的功能, 例如日志.
 */
public class ProxyModel {

}
interface IDao{
    void add(Object o);
    void delete(Object o);
    void update(int id,Object o);
    Object find(int id);
}
class SimpleDao implements IDao{

    private List<Object> mDataBase = new ArrayList<>();

    @Override
    public void add(Object o) {
        mDataBase.add(o);
    }

    @Override
    public void delete(Object o) {
        mDataBase.remove(o);
    }

    @Override
    public void update(int id,Object o) {
        mDataBase.remove(id);
        mDataBase.add(id,o);
    }

    @Override
    public Object find(int id) {
        return mDataBase.get(id);
    }
}
class DaoProxy implements IDao{

    private IDao iDao;

    public DaoProxy() {
    }

    public DaoProxy(IDao iDao) {
        this.iDao = iDao;
    }

    private void beginTransaction(){
        System.out.println("开始操作数据库");
    }
    private void commit(){
        System.out.println("结束操作数据库");
    }

    @Override
    public void add(Object o) {
        this.beginTransaction();
        iDao.add(o);
        this.commit();
    }

    @Override
    public void delete(Object o) {
        this.beginTransaction();
        iDao.delete(o);
        this.commit();
    }

    @Override
    public void update(int id, Object o) {
        this.beginTransaction();
        iDao.update(id,o);
        this.commit();
    }

    @Override
    public Object find(int id) {
        this.beginTransaction();
        Object o = iDao.find(id);
        this.commit();
        return o;
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 动态代理: 相对于静态代理, 动态代理中的代理类不需要事先与目标类相同的接口, 而且不依赖于接口的具体实现, 理论上可以代理所有类的所有方法. 但因为要考虑到涉及到的业务, 所以要求面向接口代理.
 * 实现机制: 运行时创建一个虚拟的代理类, 在代理的目标方式实际执行时, 通过java的反射技术获取到该防范对象, 并在执行前后后添加需要的操作, 这需要实现一个`InvocationHandler接口
 */
public class ProxyModel {
    public static void main(String[] args) {
        SimpleDao simpleDao = new SimpleDao();
        IDao proxy = new DaoProxy().createProxy(simpleDao);
        proxy.add("ss");
    }
}

interface IDao {
    void add(Object o);

    void delete(Object o);

    void update(int id, Object o);

    Object find(int id);
}
class SimpleDao implements IDao{

    private List<Object> mDataBase = new ArrayList<>();

    @Override
    public void add(Object o) {
        mDataBase.add(o);
    }

    @Override
    public void delete(Object o) {
        mDataBase.remove(o);
    }

    @Override
    public void update(int id,Object o) {
        mDataBase.remove(id);
        mDataBase.add(id,o);
    }

    @Override
    public Object find(int id) {
        return mDataBase.get(id);
    }
}

class DaoProxy {
    /*这里需要注意, 返回值只能是一个接口, 而不能使具体的实现类. */
    public IDao createProxy(IDao target) {
        /*此方法生成的虚拟类是根据目标的Class文件拿到的父类接口生成的, 因此不能强制转换成实现类 */
        return (IDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        beginTransaction();
                        Object invoke = method.invoke(target, args);
                        commit();
                        return invoke;
                    }
                });
    }

    private void beginTransaction() {
        System.out.println("读写开始前,开启数据库!");
    }

    private void commit() {
        System.out.println("读写结束,关闭数据库!");
    }
}

/**
 * 不关心接口的实现逻辑, 只需要取到备操作类即可.
 */
public class ProxyModel {
    public static void main(String[] args) {
        IDao proxy = new LogProxy().createProxy(SimpleDao.class);
        proxy.add("item");
        proxy.delete("asd");
        proxy.update(1,"asd");
    }
}

interface IDao {
    void add(Object o);

    void delete(Object o);

    void update(int id, Object o);

    Object find(int id);
}
class SimpleDao implements IDao{


    @Override
    public void add(Object o) {
        System.out.print("添加:  "+o.toString()+"    ");
    }

    @Override
    public void delete(Object o) {
        System.out.print("删除:  "+o.toString()+"    ");
    }

    @Override
    public void update(int id,Object o) {
        System.out.print("更新:  "+id+"    "+o.toString()+"    ");
    }

    @Override
    public Object find(int id) {
        System.out.print("查找:  "+id+"    ");
        return null;
    }
}

class LogProxy {

    public <T> T createProxy(Class<T> target) {
        return (T) Proxy.newProxyInstance(target.getClassLoader(), target.getInterfaces(),
                (proxy, method, args) -> {
                    System.out.print("开始输出日志------->");
                    System.out.print("调用方法:" + method.getName() + makeArgsText(args));
                    method.invoke(target.newInstance(),args);


                    System.out.print("<-------日志输出结束");
                    System.out.println();
                    return null;
                });
    }

    private String makeArgsText(Object[] args) {
        StringBuilder builder = new StringBuilder();
        builder.append(",   共有").append(args.length).append("个参数:  ");
        for(Object item : args) {
            builder.append(item.toString()).append(" & ");
        }
        return builder.toString();
    }
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

/**
 * 如果目标类没有实现接口, 那么`Spring AOP`会选择使用`CGLIB`来动态代理目标类.
 * CGLIB(Code Generation Library), 是一个代码生成的类库, 可以在运行时动态的生成某个类的子类.
 * CGLIB是通过继承的方式做的动态代理, 因此如果某个类被标记为Final,那么它是无法使用CGLIB做动态代理的.
 */
class SimpleDao {

    public void add(Object o) {
        System.out.println("添加:  " + o.toString() + "    ");
    }

    public void delete(Object o) {
        System.out.println("删除:  " + o.toString() + "    ");
    }

    public void update(int id, Object o) {
        System.out.println("更新:  " + id + "    " + o.toString() + "    ");
    }

    public Object find(int id) {
        System.out.println("查找:  " + id + "    ");
        return null;
    }
}

class MyMethodInterceptor implements MethodInterceptor {

    /**
     * sub:cglib生成的代理对象
     * method:被代理对象方法
     * objects:方法入参
     * methodProxy: 代理方法
     */
    @Override
    public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("======插入后者通知======");
        return object;
    }
}

class Client {
    public static void main(String[] args) {
        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        enhancer.setSuperclass(SimpleDao.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyMethodInterceptor());
        // 创建代理对象
        SimpleDao proxy = (SimpleDao) enhancer.create();
        // 通过代理对象调用目标方法
        proxy.add("add");
    }
}
posted @ 2018-12-07 21:39  X-POWER  阅读(400)  评论(0编辑  收藏  举报