java代理

java 代理模式

java 的代理有两种实现方式,1、利用java jdk自带的反射实现,InvocationHandler,2、cglib 实现的动态代理

1、JDK 实现

  1.1 描述 

     java 的动态代理 是通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h) 方法生成一个代理对象对目标对象进行增强,增强的实现在InvocationHandler      中的invoke 方法实现

  1.2 代码实现(用户通过某猪网购买车票)

  

public class JavaProxyFactory {

    /**
     * 代理工厂
     * @param target
     * @return
     */
    public static Object getProxyFactory(final Object target){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("在某猪网找到了。。。。");
                Object returnObject = method.invoke(target,args);
                System.out.println("在某猪网购买了。。。。");
                return null;
            }
        });
    }

    /**
     * 购买车票的接口
     */
    interface BuyTicketService{
        void buy();
    }

    /**
     * 用户购买车票实现
     */
    static class UserBuyTicket implements BuyTicketService{

        public void buy( ) {
            System.out.println("用户购买了火车票");
        }
    }


    public static void main(String[] args) {

        BuyTicketService buyTicketService = (BuyTicketService ) JavaProxyFactory.getProxyFactory(new UserBuyTicket());
        buyTicketService.buy();
    }
}
----------- 打印结果------

在某猪网找到了。。。。
用户购买了火车票
在某猪网购买了。。。。

  

2、cglib 实现

  2.1 描述

    cglib 实在编译时增强

  2.2 代码实现

  第一步添加依赖

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>    

  

public class CgLibProxyFactory implements MethodInterceptor {

    private Object obj;
    public Object createCgLibProxyObj(Object object){
        this.obj = object;
        Enhancer enhancer = new  Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     *
     * @param o   代理类本身
     * @param method  目标类方法
     * @param objects  目标类方法参数
     * @param methodProxy 代理类的代理方法
     * @return
     * @throws Throwable
     */
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("在某猪网找到了。。。。");
        Object returnObject = method.invoke(obj,objects);
        System.out.println("在某猪网购买了。。。。");
        return returnObject;
    }

    /**
     * 用户购买车票实现
     */
    static class UserBuyTicket {

        public void buy( ) {
            System.out.println("用户购买了火车票");
        }
    }

    public static void main(String[] args) {
        //目标对象
        UserBuyTicket userBuyTicket = ( UserBuyTicket )new CgLibProxyFactory()
                .createCgLibProxyObj(new UserBuyTicket());
        userBuyTicket.buy();
    }
-----打印结果

在某猪网找到了。。。。
用户购买了火车票
在某猪网购买了。。。。

  

3、两者比较

  优点            缺点        
JKD代理 1、运行时增强编译快jar包太大时可选; 1、运行时增强执行效率相对较低;2、实现必须依赖接口实现
CGLIB代理 1、编译时增强,jar包不大时可选;2、任何类都可以实现,无需依赖接口 1、编译时增强,执行效率高

  

  

posted @ 2019-11-21 10:46  wangshunyao  阅读(143)  评论(0编辑  收藏  举报