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

结果如图:

如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
原文地址:https://www.cnblogs.com/Frank99/p/8918105.html