原 java学习(十四)-java代理

一、java代理

案例:https://segmentfault.com/a/1190000011291179

1.1、代理模式:
  • 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
1.2、代理的种类:
  • 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 静态代理类需要与目标类实现相同的接口,重新接口方法;并在代理类中需要有对代理类的引用。
  • 动态代理在程序运行时,运用反射机制动态创建而成。(jdk提供了一个API java.lang.reflect.InvocationHandler的类,可以让我们在jvm调用某个类的方法时动态的为这些方法做某些事,java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。动态代理类实现InvacationHandler接口,并将目标对象注入到代理类中,利用反射机制来执行目标对象的方法)。动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。
    • gdk代理:JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。
    • cglib代理:cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
二、实战讲解
2.1、静态代理
  • 创建count接口
/**
 * Copyright (C), 2015-2019
 * FileName: Count
 * Author:   qianwenjun
 * Date:     2019/3/16 08:40
 * Description:
 */
package com.qwj.study.proxy.jintaiProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public interface Count {


    // 查看账户方法
    public void queryCount();

    // 修改账户方法
    public void updateCount();


}
  • 创建其实现
/**
 * Copyright (C), 2015-2019
 * FileName: CountImpl
 * Author:   qianwenjun
 * Date:     2019/3/16 08:41
 * Description:
 */
package com.qwj.study.proxy.jintaiProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class CountImpl implements Count {

    @Override
    public void queryCount() {
        System.out.println("查看账户方法...");

    }

    @Override
    public void updateCount() {
        System.out.println("修改账户方法...");

    }
}
  • 创建代理类并测试
/**
 * Copyright (C), 2015-2019
 * FileName: CountProxy
 * Author:   qianwenjun
 * Date:     2019/3/16 08:46
 * Description:
 */
package com.qwj.study.proxy.jintaiProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class CountProxy implements Count {

    private CountImpl countImpl;

    /**
     * 覆盖默认构造器
     *
     * @param countImpl
     */
    public CountProxy(CountImpl countImpl) {
        this.countImpl = countImpl;
    }

    @Override
    public void queryCount() {
        System.out.println("事务处理之前");
        // 调用委托类的方法;
        countImpl.queryCount();
        System.out.println("事务处理之后");
    }

    @Override
    public void updateCount() {
        System.out.println("事务处理之前");
        // 调用委托类的方法;
        countImpl.updateCount();
        System.out.println("事务处理之后");

    }


    public static void main(String[] args) {
        CountImpl countImpl = new CountImpl();
        CountProxy countProxy = new CountProxy(countImpl);
        countProxy.updateCount();
        countProxy.queryCount();

    }
}

运行结果如下
在这里插入图片描述

2.2、动态代理-jdk代理
  • 创建Bookfaced接口
/**
 * Copyright (C), 2015-2019
 * FileName: BookFaced
 * Author:   qianwenjun
 * Date:     2019/3/16 08:36
 * Description:
 */
package com.qwj.study.proxy.gdkProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public interface BookFaced {

    public void addBook();
}
  • 创建其实现
/**
 * Copyright (C), 2015-2019
 * FileName: BookFacedIml
 * Author:   qianwenjun
 * Date:     2019/3/16 08:37
 * Description:
 */
package com.qwj.study.proxy.gdkProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class BookFacedIml implements BookFaced {

    @Override
    public void addBook() {
        System.out.println("增加图书方法。。。");
    }

}
  • 创建jdk代理类并测试
/**
 * Copyright (C), 2015-2019
 * FileName: BookFacedGdkProxy
 * Author:   qianwenjun
 * Date:     2019/3/16 08:49
 * Description:
 */
package com.qwj.study.proxy.gdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 〈JDK动态代理代理类〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class BookFacedGdkProxy implements InvocationHandler {

    private Object target;
    /**
     * 绑定委托对象并返回一个代理类
     * @param target
     * @return
     */
    public Object bind (Object target) {
        this.target = target;
        //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
        Object result=null;
        System.out.println("事物开始");
        //通过反射机制执行目标对象的方法
        result=method.invoke(target, args);
        System.out.println("事物结束");
        return result;

    }


    public static void main(String[] args) {
        BookFacedGdkProxy proxy = new BookFacedGdkProxy();
        BookFaced bookProxy = (BookFaced) proxy.bind(new BookFacedIml());
        bookProxy.addBook();
    }
}

在这里插入图片描述

2.3、动态代理-cglib代理
  • 创建Bookfaced接口
/**
 * Copyright (C), 2015-2019
 * FileName: BookFaced
 * Author:   qianwenjun
 * Date:     2019/3/16 08:36
 * Description:
 */
package com.qwj.study.proxy.cglibProxy;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public interface BookFaced {

    public void addBook();
}
  • 创建类,但不是实现Bookfaced接口
/**
 * Copyright (C), 2015-2019
 * FileName: BookFacesIml2
 * Author:   qianwenjun
 * Date:     2019/3/16 09:02
 * Description:
 */
package com.qwj.study.proxy.cglibProxy;

/**
 * 〈这个是没有实现接口的实现类〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class BookFacesIml2 {

    public void addBook() {
        System.out.println("增加图书的普通方法...");
    }
}
  • 创建cglib代理类并测试
/**
 * Copyright (C), 2015-2019
 * FileName: BookFacedCglibProxy
 * Author:   qianwenjun
 * Date:     2019/3/16 09:03
 * Description:
 */
package com.qwj.study.proxy.cglibProxy;

//import org.aopalliance.intercept.MethodInterceptor;
//import org.springframework.cglib.proxy.Enhancer;
//import org.springframework.cglib.proxy.MethodProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;


import java.lang.reflect.Method;

/**
 * 〈〉
 *
 * @author qianwenjun
 * @create 2019/3/16
 * @since 1.0.0
 */
public class BookFacedCglibProxy implements MethodInterceptor {


    private Object target;

    /**
     * 创建代理对象
     *
     * @param target
     * @return
     */
    public Object getInstance (Object target) {

        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        //创建回调方法
        enhancer.setCallback(this);
        return  enhancer.create();

    }

    @Override
    // 回调方法
    public Object intercept (Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

        System.out.println("事物开始");
        proxy.invokeSuper(obj, args);
        System.out.println("事物结束");
        return null;
    }


    public static void main(String[] args) {
        BookFacedCglibProxy cglib=new BookFacedCglibProxy();
        BookFacesIml2 bookCglib=(BookFacesIml2)cglib.getInstance(new BookFacesIml2());
        bookCglib.addBook();
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值