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"); } }

浙公网安备 33010602011771号