• Java静态代理和动态代理总结


    静态代理

    第一种实现(基于接口):

    1》接口

    public interface Hello {
        void say(String msg);
    }

    2》目标类,至少实现一个接口

    public class HelloImpl implements Hello {
    public void say(String msg) {
    System.out.println("Hi,"+msg);
    }
    }

    3》代理类(与目标类实现相同接口,从而保证功能一致)

    public class HelloProxy implements Hello{

    private Hello hello;

    public HelloProxy(Hello hello){
    this.hello = hello;
    }

    public void say(String msg){
    before();
    hello.say(msg);
    after();
    }
    private void before(){
    System.out.println("Before");
    }
    private void after(){
    System.out.println("After");
    }
    }

    3》测试

    /**
    * @Author LZHL
    * @Create 2017-02-19 10:26
    * @Description
    */
    public class Main {
    public static void main(String[] args) throws Exception {
    HelloImpl target = new HelloImpl();
    HelloProxy proxy = new HelloProxy(target);
    proxy.say("LZHL");
    }
    }

    第二种实现(基于目标类):

    1>目标类

    public class HelloTarget {
    public void sayHello(String name){
    System.out.println("Hi,"+name);
    }
    }

    2>代理类(通过继承目标类,保证功能一致)

    public class HelloProxy extends HelloTarget{
      private HelloTarget target;
      public HelloProxy(HelloTarget target){
        this.target = target;
      }
      @Override
    public void sayHello(String name) {
    this.before();
    target.sayHello(name);
    this.after();
    }
    private void before(){
    System.out.println("Before");
    }
    private void after(){
    System.out.println("After");
    }
    }

    3>测试

    public class Main {
    public static void main(String[] args) throws Exception {
    HelloTarget target = new HelloTarget();
        HelloProxy proxy= new HelloProxy(target);
    proxy.sayHello("LZHL");
    }
    }

    动态代理

    动态代理的代理类是在程序运行期间动态生成的,也有两种实现,一种是JDK动态代理,一种是CGLib动态代理

    1》JDK动态代理(基于接口实现,与目标类实现相同接口,从而保证功能一致)

    /**
    * @Author LZHL
    * @Create 2017-02-19 12:46
    * @Description
    */
    public class Main {
    public static void main(String[] args){

    final HelloImpl target = new HelloImpl();

    Object proxyInstance = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
    /*
    * proxy: 代理对象
    * method: 目标对象的方法对象
    * args: 目标对象方法的参数
    * return: 目标对象方法的返回值
    */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("before");
    Object retValue = method.invoke(target, args);
    System.out.println("after");
    return retValue;
    }
    });
    Hello proxy = (Hello) proxyInstance;
    proxy.say("LYX");

    //可以把InvocationHandler提取出来,单独写一个类,为了方便大家看,这里我用内部类的形式
            class JDKProxy implements InvocationHandler {
    private Object target;
    public JDKProxy(Object target){
    this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    before();
    Object result = method.invoke(target, args);
    after();
    return result;
    }
    private void before(){
    System.out.println("Before");
    }
    private void after(){
    System.out.println("After");
    }
    }
    InvocationHandler ih = new JDKProxy(target);
    Object proxyInstance2 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), ih);
    Hello proxy2 = (Hello) proxyInstance2;
    proxy2.say("LZHL");
    }
    }
    
    

    2》CGLib动态代理(基于目标类,通过继承目标类,从而保证功能一致),需要导入cglib-3.2.4.jar包

    pom.xml

    <dependencies>
    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.4</version>
    </dependency>

    </dependencies>

    1)目标类

    public class Hi {
    public void sayHi(String msg){
    System.out.println("Hi,"+msg);
    }
    }

    2)测试

    /**
    * @Author LZHL
    * @Create 2017-02-19 13:19
    * @Description
    */
    public class Main {
    public static void main(String[] args) {
    Enhancer enhancer = new Enhancer();
    //设置父类
    enhancer.setSuperclass(Hi.class);
    //设置回调函数
    enhancer.setCallback(new MethodInterceptor() {
    public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("before");
    Object retValue = methodProxy.invokeSuper(target, args);
    System.out.println("after");
    return retValue;
    }
    });
    Object proxy = enhancer.create();
    Hi hi = (Hi) proxy;
    hi.sayHi("LXY");

    //可以把MethodInterceptor提取出来,单独写一个类,为了方便大家看,这里我用内部类的形式
    class CGLibProxy implements MethodInterceptor {

    public <T> T getProxy(Class<T> clazz){
    return (T) Enhancer.create(clazz, this);
    }
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    before();
    Object result = proxy.invokeSuper(target, args);
    after();
    return result;
    }
    private void before(){
    System.out.println("Before");
    }
    private void after(){
    System.out.println("After");
    }
    }

    CGLibProxy cgLibProxy = new CGLibProxy();
    Hi hi2 = cgLibProxy.getProxy(Hi.class);
    hi2.sayHi("LZHL");
    }
    }


  • 相关阅读:
    (转)java web自定义分页标签
    关于在springmvc下使用@RequestBody报http status 415的错误解决办法
    (转)解决点击a标签返回页面顶部的问题
    优先队列详解priority_queue .RP
    7.23 学习问题
    7.24 学习问题
    7.25 学习问题
    python装饰器学习笔记
    SQL数据库简单操作
    form属性method="get/post
  • 原文地址:https://www.cnblogs.com/lzhl/p/6416063.html
Copyright © 2020-2023  润新知