代理模式

来源:互联网 发布:商品sku数据库设计 编辑:程序博客网 时间:2024/06/05 11:59

硬编码

直接在业务源代码中修改

静态代理

//接口public interface TeamService {      void updateObject();      void insertObject();}
//被代理类public class TeamSerivceImpl implements TeamService {    @Override    public void updateObject() {        System.out.println("==updateObject==");    }    @Override    public void insertObject() {        System.out.println("==insertObject==");    }}
//需要增加业务public class TimeAspect {     public void begin(){        System.out.println("method.start="+System.nanoTime());      }     public void after(){        System.out.println("method.end="+System.nanoTime());     }}
//代理类public class TeamServiceProxy implements TeamService {    private TeamService teamService;    private TimeAspect timeAspect;    public TeamServiceProxy(TeamService teamService) {        this.teamService=teamService;    }    public TeamServiceProxy(        TeamService teamService,TimeAspect timeAspect) {        this.teamService=teamService;        this.timeAspect=timeAspect;    }    @Override    public void updateObject() {        timeAspect.begin();        //System.out.println("method.start="+System.nanoTime());        teamService.updateObject();        //System.out.println("method.end="+System.nanoTime());        timeAspect.after();    }    @Override    public void insertObject() {        timeAspect.begin();        //System.out.println("method.start="+System.nanoTime());        teamService.insertObject();        //System.out.println("method.end="+System.nanoTime());        timeAspect.after();    }}
//测试public class TestTeamService {    public static void main(String[] args) {        //如何调用业务实现?        TeamService teamService=        //new TeamServiceProxy(new TeamSerivceImpl());        new TeamServiceProxy(new TeamSerivceImpl(),new TimeAspect());        teamService.insertObject();        teamService.updateObject();        //假如将这种写法理解为代理模式        //1)代理对象是谁? TeamServiceProxy        //2)被代理对象是谁?TeamSerivceImpl        //代理对象与被对象有什么共性?        //1)都是一个具体类型的对象        //2)它们都实现了共同的接口.        //代理模式中的三种角色:        //1)抽象角色        //2)代理角色        //3)被代理角色        //代理模式可以帮我们解决什么问题?        //在不修改核心业务的前提下添加或扩展新的业务.        //在本业务中TeamServiceProxy代理类可以代理哪些对象?        //1)实现了TeamService接口的所有对象        //这种实现存在缺陷吗?有什么缺陷?可以应用在什么场景?        //缺陷:只能代理指定接口的类,接口多时就可能要写多个代理类        //应用场景:业务相对单一,需要代理的接口比较少的场景.        }}

动态代理

使用上部分代码

//被代理类public class ProductServiceImpl {    public void insertObject(){        System.out.println("insert product");    }}public class ProductServiceImpl {    public void insertObject(){        System.out.println("insert product");    }}
/**扩展业务:事务处理 * 在spring用于类似事务处理的这个对象通常会将其理解为切面 * */public class TransactionAspect {     /**开启事务*/     public void begin(){         System.out.println("begin transaction");     }     /**结束事务(commit,rollback)*/     public void end(){         System.out.println("end transaction");     }}
/*** * 动态代理:(不改变原有代码的情况下以一种简化的方式添加扩展功能) * 1)对象运行时动态创建代理对象.(无需手动编写代理类,例如静态代理) * 2)代理的对象必须实现了某个或某些接口.(与静态代理相同) * 3)借助JDK及反射机制实现. * 动态代理最大优势:无需编写静态代理类,可以同时为多个接口创建代理 * 动态代理最大劣势:代码可读性相对较差(初学者不容理解), * 被代理对象必须实现了接口. */public class TestDyServiceProxy {    /**代理对象底层会交给此handler处理业务     * 1)核心业务     * 2)扩展业务     * */    static class ServiceHandler implements                       InvocationHandler{        /*核心业务对象(被代理对象)*/        private Object target;        public ServiceHandler(Object target) {            this.target=target;        }        /*扩展业务切面对象*/        private TransactionAspect txAspect;        public void setTxAspect(TransactionAspect txAspect) {            this.txAspect = txAspect;        }        /**调用业务操作:在执行代理对象的业务方法时         * 自动执行此方法         * --->1)tServiceProxy.insertObject(args)         * --->2)handler.invoke(proxy,method,args)         * --->3)method.invoke(target,args)         * */        @Override        public Object invoke(                Object proxy,//指向代理对象                Method method,//指向接口中方法对象                Object[] args) //指向接口方法对象中的实际参数                        throws Throwable {            //开启事务            txAspect.begin();            //执行核心业务            Object result=            //执行目标对象target的核心业务(method)            method.invoke(target, args);            //结束事务            txAspect.end();            return result;        }    }    /**为目标对象target创建代理对象*/    static Object newProxy(Object target){        ServiceHandler sHandler=                new ServiceHandler(target);        sHandler.setTxAspect(new TransactionAspect());        //借助JDK中的Proxy类的静态方法创建代理对象        return Proxy.newProxyInstance(        //代理类要使用的类加载器        target.getClass().getClassLoader(),        //代理类应该实现的接口        target.getClass().getInterfaces(),        sHandler);//handler(处理器:业务调用)    }    public static void main(String[] args) throws Exception{        //1.需求        //1).为ProjectService业务方法添加事务处理        //2).为TeamService业务方法添加事务处理.        //2.设计(借助动态代理)        //3.实现        //创建XxxServiceImpl的代理对象        ProjectService pService=        (ProjectService)newProxy(        new ProjectServiceImpl());        TeamService tService=        (TeamService)newProxy(        new TeamSerivceImpl());        //调用代理对象的业务方法        pService.saveObject();        tService.updateObject();        //以上方法在执行时底层会调用InvocationHandler对象        //的invoke方法    }}/*** * Proxy: 负责创建代理对象 * InvocationHandler:负责处理业务(核心和非核心) */
原创粉丝点击