zoukankan      html  css  js  c++  java
  • jdk 动态代理实现对目标对象的增强

    因为学习 spring框架的 AOP 所以,这里复习下动态代理,但是 spring 的底层动态代理实现是 cglib,jdk 这种呢可以引导新手入门

    spring AOP 横向抽取机制 最典型的应用当属 log ,transaction 了,具体可以从配置文件的配置以及注解看出

    首先基于 jdk 的动态代理需要借助于 

    jdk 中 reflect 包下(java.lang.reflect.Proxy)的 Proxy

    以及(java.lang.reflect.InvocationHandler) InvacationHandler

    去生成代理对象。

    局限性是这种动态代理只适用于对有接口的类实现动态代理

    原理其实是,利用反射机制先生成要被代理对象的同级对象然后对这个同级对象进行增强

    所以这里需要传入接口

     下面是代码部分详解:

    首先我们定义一个简单的 动物接口 IAnimal 里面有一个简单方法 move

    package com.ghc.test;
    
    public interface IAnimal {
        void move();
    }
    com.ghc.test.IAnimal

    然后呢,我们定义一个要被代理的类 Cat,这个类实现了 IAnimal 接口

    package com.ghc.test;
    
    public class Cat implements IAnimal {
        @Override
        public void move() {
            System.out.println("cat run...");
        }
    }
    com.ghc.test.Cat

    接下来就是我们 处理器的定义了,这个唤醒处理器呢有个规范就是必须实现 接口 java.lang.reflect.InvocationHandler;

    覆写里面的 invoke 方法,并且在 invoke 方法中做我们的增强,具体代码如下:

    package com.ghc.test;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class AnimalInvocationHandler implements InvocationHandler {
        // 定义要被代理的类
        private Object tar;
        public AnimalInvocationHandler(Object tar){
            this.tar=tar;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("前置增强处......");
            Object result = method.invoke(tar,args);
            System.out.println("后置增强处......");
            return result;
        }
        public Object getProxyInstance(){
            return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),tar.getClass().getInterfaces(),this);
        }
    }
    com.ghc.test.AnimalInvocationHandler

    当然,上面其中一个方法 getProxyInstance 其实是可以定义在使用的地方的。这都不是重点

    重点来了,就是我们如何使用呢:

    import com.ghc.test.AnimalInvocationHandler;
    import com.ghc.test.Cat;
    import com.ghc.test.IAnimal;
    import org.junit.Test;
    
    public class DynamicProxyTest {
        @Test
        public void testCatProxy(){
            //先创建要被代理的对象
            Cat cat = new Cat();
            AnimalInvocationHandler animalInvocationHandler=new AnimalInvocationHandler(cat);
            IAnimal catProxy = (IAnimal) animalInvocationHandler.getProxyInstance();
            catProxy.move();
        }
    }
    DynamicProxyTest

    结果如图:

    如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
  • 相关阅读:
    winform 上传文件 (多种)
    获取Treeview中CheckBox选中项的技巧(winform)
    C#中class与struct的区别
    在SQL Server数据库中批量导入数据的四种方法
    小东西WinForm的等待窗口
    查询及删除重复记录的方法
    一些算法的复习和整理,争取每天一个算法
    POJ 2965 The Pilots Brothers' refrigerator
    HDU 1492 The number of divisors(约数) about Humble Numbers
    HDU 1495 非常可乐
  • 原文地址:https://www.cnblogs.com/Frank99/p/8918105.html
Copyright © 2011-2022 走看看