spring aop原理解析-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:  指代的是调用真实对象某个方法时接受的参数

spring aop 其内部采用的设计模式为代理模式.

package com.bird;

/**
 * 公共接口
 * 
 * @author li
 * 
 */
public interface Test {
    public void addUser(String userName);

    public void removeUser(String userName);

}
package com.bird;

/**
 * 主题角色
 * 
 * @author li
 * 
 */
public class TestInterface implements Test {

    public void addUser(String userName) {
        System.out.println("i am adding a new user:" + userName);
    }

    public void removeUser(String userName) {
        System.out.println("i am removing a new user:" + userName);
    }
package com.bird;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理对象
 * 
 * @author li
 * 
 */
public class ProxyUser implements InvocationHandler {
    private Object realObject;

    public Object newProxyInstance(Object realObject) {
        this.realObject = realObject;
        return Proxy.newProxyInstance(realObject.getClass().getClassLoader(),
                realObject.getClass().getInterfaces(), this);

    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        try {
            /**
             * 代理对象中的方法 equals[Ljava.lang.Class;@487f6155
             * toString[Ljava.lang.Class;@22cf38a2
             * hashCode[Ljava.lang.Class;@528f2588
             * removeUser[Ljava.lang.Class;@33e92e10
             * addUser[Ljava.lang.Class;@11cf3710
             * isProxyClass[Ljava.lang.Class;@3b280492
             * getProxyClass[Ljava.lang.Class;@40442b95
             * newProxyInstance[Ljava.lang.Class;@3b896429
             * getInvocationHandler[Ljava.lang.Class;@390ede48
             * wait[Ljava.lang.Class;@7f23663b wait[Ljava.lang.Class;@6d0cecb2
             * wait[Ljava.lang.Class;@6b87d20c
             * getClass[Ljava.lang.Class;@21ef48fb
             * notify[Ljava.lang.Class;@64a06824
             * notifyAll[Ljava.lang.Class;@5f154718
             */

            for (Method m : proxy.getClass().getMethods()) {
                System.out.println(m.getName() + m.getParameterTypes());
            }
            System.out.println("before operate " + method.getName());
            method.invoke(realObject, args);
            System.out.println("after operate " + method.getName());
        } catch (Exception e) {
            System.out.println("error " + method.getName());
            throw e;

        }
        return null;
    }

    public static void main(String[] args) {
        ProxyUser user = new ProxyUser();
        // 新创建的接口引用指向代理对象,当该引用调用接口中的方法时,实际上执行的为代理对象的方法

        Test test = (Test) user.newProxyInstance(new TestInterface());
        test.removeUser("li");
    }
}

 

 
posted @ 2015-11-05 15:51  程序猿进化之路  阅读(162)  评论(0)    收藏  举报