标签:and 添加 代理类 面向切面 拦截器 额外 [] stat tar
Spring是一种为了减缓程序开发复杂性开发的一种基于AOP和IOC等思想的集合框架。
AOP:(AOP为Aspect Oriented Programming的缩写,即面向切面编程(也叫面向方面),是一种可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
如下运用了动态代理的实例
Animal.java :委托类(被代理的类),注:委托类实际是一个接口,这里为了方便描述,所以这里用委托类
1 public interface Animal { 2 public void run(); 3 public void jump(); 4 }
Dog.java 实现了委托类的子类
public class Dog implements Animal{ public void run(){ System.out.println("小狗开始跑!"); } public void jump(){ System.out.println("小狗开始跳!"); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * InvocationHandle接口的实现类的实例相当于一个拦截器,作用是拦截被代理(委托)对象中的方法 * * @author Administrator * */ public class MyProxy implements InvocationHandler{ private Object targetObject; /** * 通过该构造方法传入该拦截类需要拦截(绑定)的委托类对象 * * @param targetObject 委托对象 */ public MyProxy(Object targetObject){ this.targetObject = targetObject; } /** * 返回一个代理类 * @param target * @return */ // public Object createProxyInstance(Object targetObject) { // return // } /** * @param proxy:指被代理的对象。 * @param method:要调用的方法 * @param args:方法调用时所需要的参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //注入需要调用的方法 (额外功能) command(); //执行被代理对象的方法,如果方法有返回值则赋值给ret Object ret = method.invoke(targetObject, args); //注入需要调用的方法 (额外功能) award(); return ret; } private void command() { System.out.println("驯兽师发出命令!"); } private void award(){ System.out.println("驯兽师给与奖励!"); } }
MyProxy.java:拦截类(都必须实现InvocationHandler接口,覆盖里面的invoke方法),其作用直观地说,就是把委托类(Animal)中的每一个方法都等价于invoke方法。
当在用代理实例(详见Test.java中的注解)调用对应的方法时,实际上是在执行invoke方法。此外还可以自己在invoke方法里面添加自己想要添加的内容,这样就保证了在原有功能不变的基础上增加了
额外的功能的目的,详见下面的代码中的注释。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * InvocationHandle接口的实现类的实例相当于一个拦截器,作用是拦截被代理(委托)对象中的方法 * * @author Administrator * */ public class MyProxy implements InvocationHandler{ private Object targetObject; /** * 通过该构造方法传入该拦截类需要拦截(绑定)的委托类(Animal)对象 * * @param targetObject 委托类对象 */ public MyProxy(Object targetObject){ this.targetObject = targetObject; } /** * 返回一个代理类 * @param target * @return */ // public Object createProxyInstance(Object targetObject) { // return // } /** * @param proxy:指被代理的对象。 * @param method:要调用的方法 * @param args:方法调用时所需要的参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //注入需要调用的方法 command(); //执行被代理对象的方法,如果方法有返回值则赋值给ret Object ret = method.invoke(targetObject, args); //注入需要调用的方法 award(); return ret; } private void command() { System.out.println("驯兽师发出命令!"); } private void award(){ System.out.println("驯兽师给与奖励!"); } }
Test.java
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { //(Animal)委托类对象 Animal animal = new Dog(); // 确定(MyProxy)拦截类需要拦截的对象(animal),并产生一个拦截类对象(hander) //该对象的作用是拦截委托类(animal)中的指定方法。 MyProxy hander = new MyProxy(animal); /** * 产生委托类(Animal)对象的代理的实例(animalProxy) * new ProxyInstance(委托类对象的类加载器,委托类对象所实现的所有接口,拦截类对象) */ Animal animalProxy = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), hander); /** * 当用代理实例(animalProxy)调用委托类(Animal)里面的对应的方法时,会自动转到拦截类 * (MyProxy)中的invoke方法去执行(该方法的执行是通过反射来实现的) */ //对 animalProxy.run(); //实际上会执行拦截类(Proxy)中的(invoke方法) animalProxy.jump(); } }
以上实例其实不是很规范,当更容易理解动态代理的执行过程。相对规范的写法如下
Animal.java
public interface Animal { public void run(); public void jump(); }
Dog.java
1 public class Dog implements Animal{ 2 public void run(){ 3 System.out.println("小狗开始跑!"); 4 } 5 public void jump(){ 6 System.out.println("小狗开始跳!"); 7 } 8 }
MyProxy.java
package com.yhs.aop.example; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * InvocationHandle接口的实现类的实例相当于一个拦截器,作用是拦截被代理(委托)对象中的方法 * * @author Administrator * */ public class MyProxy implements InvocationHandler{ private Object targetObject; /** * 通过该方法传入该拦截类需要拦截(绑定)的委托类对象 * * @param targetObject 委托对象 */ public void bind(Object targetObject){ this.targetObject =targetObject; } /** * 返回一个代理类的实例 * @param target * @return */ public Object createProxyInstance() { return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } /** * @param proxy:指被代理的对象。 * @param method:要调用的方法 * @param args:方法调用时所需要的参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //注入需要调用的方法 command(); //执行被代理对象的方法,如果方法有返回值则赋值给ret Object ret = method.invoke(targetObject, args); //注入需要调用的方法 award(); return ret; } private void command() { System.out.println("驯兽师发出命令!"); } private void award(){ System.out.println("驯兽师给与奖励!"); } }
Test.java
package com.yhs.aop.example; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { //(Animal)委托类对象 Animal animal = new Dog(); //产生一个拦截类对象(hander),该对象的作用是拦截委托类(animal)中的指定方法。 MyProxy hander = new MyProxy(); //确定(MyProxy)拦截类需要拦截(绑定)的对象(animal) hander.bind(animal); //产生委托类(animal)的代理的实例(animalProxy) Animal animalProxy = (Animal) hander.createProxyInstance(); /** * 当用代理实例(animalProxy)调用委托类(Animal)里面的对应的方法时,会自动转到拦截类 * (MyProxy)里从InvocationHander接口的实现方法invoke去执行(该方法的执行时通过反射来实现的) */ //对 animalProxy.run(); animalProxy.jump(); } }
标签:and 添加 代理类 面向切面 拦截器 额外 [] stat tar
原文地址:http://www.cnblogs.com/studyCenter/p/6601003.html