Java 反射以及动态代理,来看就懂了( 二 )


文章插图
 
③ 反射调用私有方法
【Java 反射以及动态代理,来看就懂了】Class myClass = Class.forName("com.interview.chapter4.MyReflect");// 创建实例对象(相当于 new )Object object = myClass.newInstance();Method method3 = myClass.getDeclaredMethod("privateMd");method3.setAccessible(true);method3.invoke(object);

Java 反射以及动态代理,来看就懂了

文章插图
 
反射使用总结
反射获取调用类可以通过 Class.forName(),反射获取类实例要通过 newInstance(),相当于 new 一个新对象,反射获取方法要通过 getMethod(),获取到类方法之后使用 invoke() 对类方法进行调用 。如果是类方法为私有方法的话,则需要通过 setAccessible(true) 来修改方法的访问限制,以上的这些操作就是反射的基本使用 。
动态代理动态代理可以理解为,本来应该自己做的事情,却交给别人代为处理,这个过程就叫做动态代理 。
动态代理的使用场景
动态代理被广为人知的使用场景是 Spring 中的面向切面编程(AOP) 。例如,依赖注入 @Autowired 和事务注解 @Transactional 等,都是利用动态代理实现的 。
动态代理还可以封装一些 RPC 调用,也可以通过代理实现一个全局拦截器等 。
动态代理和反射的关系
JDK 原生提供的动态代理就是通过反射实现的,但动态代理的实现方式还可以是 ASM(一个短小精悍的字节码操作框架)、cglib(基于 ASM)等,并不局限于反射 。
下面我们分别来看:JDK 原生动态代理和 cglib 的实现 。
1)JDK 原生动态代理
interface Animal {    void eat();}class Dog implements Animal {    @Override    public void eat() {        System.out.println("The dog is eating");    }}class Cat implements Animal {    @Override    public void eat() {        System.out.println("The cat is eating");    }} 
Java 反射以及动态代理,来看就懂了

文章插图
 
// JDK 代理类class AnimalProxy implements InvocationHandler {    private Object target; // 代理对象    public Object getInstance(Object target) {        this.target = target;        // 取得代理对象        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("调用前");        Object result = method.invoke(target, args); // 方法调用        System.out.println("调用后");        return result;    }}
Java 反射以及动态代理,来看就懂了

文章插图
 
 public static void main(String[] args) {    // JDK 动态代理调用    AnimalProxy proxy = new AnimalProxy();    Animal dogProxy = (Animal) proxy.getInstance(new Dog());    dogProxy.eat();}
Java 反射以及动态代理,来看就懂了

文章插图
 
以上代码,我们实现了通过动态代理,在所有请求前、后都打印了一个简单的信息 。
注意: JDK Proxy 只能代理实现接口的类(即使是 extends 继承类也是不可以代理的) 。
2)cglib 动态代理
要是用 cglib 实现要添加对 cglib 的引用,如果是 maven 项目的话,直接添加以下代码:
<dependency>    <groupId>cglib</groupId>    <artifactId>cglib</artifactId>    <version>3.2.12</version></dependency>


推荐阅读