设为首页 加入收藏

TOP

Java的动态代理机制详解(一)
2016-12-14 08:15:13 】 浏览:473
Tags:Java 动态 代理 机制 详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾。


在Java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的:


InvocationHandler:


InvocationHandler is the interface implemented by the invocation handler of a proxy instance.


Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.


每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:


Object invoke(Object proxy, Method method, Object[] args) throws Throwable


我们看到这个方法一共接受三个参数,那么这三个参数分别代表什么呢?


Object invoke(Object proxy, Method method, Object[] args) throws Throwable


proxy:  指代我们所代理的那个真实对象
method:  指代的是我们所要调用真实对象的某个方法的Method对象
args:  指代的是调用真实对象某个方法时接受的参数


如果不是很明白,等下通过一个实例会对这几个参数进行更深的讲解。


接下来我们来看看Proxy这个类:


Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.


Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:


public static Object newProxyInstance(ClassLoader loader, Class<>[] interfaces, InvocationHandler h) throws IllegalArgumentException


Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.


这个方法的作用就是得到一个动态的代理对象,其接收三个参数,我们来看看这三个参数所代表的含义:


public static Object newProxyInstance(ClassLoader loader, Class<>[] interfaces, InvocationHandler h) throws IllegalArgumentException


loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载


interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了


h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上


好了,在介绍完这两个接口(类)以后,我们来通过一个实例来看看我们的动态代理模式是什么样的:


首先我们定义了一个Subject类型的接口,为其声明了两个方法:


public interface Subject
{
public void rent();

public void hello(String str);
}


接着,定义了一个类来实现这个接口,这个类就是我们的真实对象,RealSubject类:


public class RealSubject implements Subject
{
@Override
public void rent()
{
System.out.println("I want to rent my house");
}

@Override
public void hello(String str)
{
System.out.println("hello: " + str);
}
}


下一步,我们就要定义一个动态代理类了,前面说个,每一个动态代理类都必须要实现 InvocationHandler 这个接口,因此我们这个动态代理类也不例外:


public class DynamicProxy implements InvocationHandler
{
// 这个就是我们要代理的真实对象
private Object subject;

// 构造方法,给我们要代理的真实对象赋初值
public DynamicProxy(Object subject)
{
this.subject = subject;
}

@Override
public Object invoke(Object object, Method method, Object[] args)
throws Throwable
{
//  在代理真实对象前我们可以添加一些自己的操作
System.out.println("before rent house");

System.out.println("Method:" + method);

// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(subject, args);

//  在代理真实对象后我们也可以添加一些自己的操作
System.out.println("after rent house");

return null;
}


}


最后,来看看我们的Client类:


public class Client
{
public static

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇《Linux内核设计与实现》读书笔记 下一篇JavaScript数组方法reduce解析

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目