标签:
说明:图(2)中的红色红色斜体的类或接口是由java类库提供的即 Proxy和InvocationHandler 是java对动态代理的支持
/** *抽象主题 **/
/**
*一个接口,规范RealSubject和由java提供的Proxy动态生成的代理类的形状(说明实现了RealSubject的类就应该长这样)
*该类有一个subjectMethod动态代理就是在执行该方法的前后做一些操作
**/
package dproxy;
interface Subject { void subjectMethod(int a,int b); }
/** *具体主题 **/
/**
*实现了Subject接口,并且覆盖了subjectMethod方法
**/
package dproxy; public class RealSubject implements Subject { @Override public void subjectMethod(int a, int b) { // TODO Auto-generated method stub System.out.println(a+"+"+b +"="+(a+b)); } }
/** *代理处理 **/ package dproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyHandler implements InvocationHandler { private Object subject; public ProxyHandler(Object subject) { // TODO Auto-generated constructor stub this.subject = subject; } /**
*从图(2)可以看到ProxyHandler实现了由java提供的对动态代理支持的InvocationHandler接口,该接口由个invoke方法该方法的
*功能是在具体主题RealSubject的subjectMethod方法执行前后添加一些其它功能,由于ProxyHandler的功能特性,我把它叫做代理处理
*注意这里并不是代理类,代理类的一个功能委派类。
**/
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
*我们看到invoke有三个参数,其中proxy这个参数是指由java的Proxy类调用newProxyInstance方法动态创建的一个代理,也就是动态代理中的那个代理类,就是它
*在图(1)中它是由我们集成自图(1)中的Subject,与Subject有相同结构的一个类,但是在图(2)中是动态生成的,虽然是动态生成的,但是它依然动态的继承了Subject接口
*并且会将在再realMethod方法前后添加功能的责任委派给ProxyHandler.
*但是有个问题,我们在这里并没有显示使用
*这个proxy那么,它的作用是什么。这就涉及到了AOP这个概念,java语言是面向对象的,即OOP。在OOP中有封装,继承,多态的概念。但是有个问题,就是有很多类
*会有一些共同的行为,例如web中的日志。处理日志的方法都是相同的,但是由于java的OOP我们只能在每个需要处理日志的类中增加处理日志的方法,这样就会导致代码的冗余。
*于是就有了AOP,以后每个类的日志我们可以在这个方法里做了。这个方法可以被多个RealSubject使用,每个RealSubject的任意一个方法都可以使用,我在这里只展示了一个
*RealSubject,及这个RealSubject中的一个方法。由于要被多个RealSubject使用,所以需要多个动态生成的代理。因为最终的realMethod方法的调用是由动态代理类开始,
*然后委托给ProxyHandler,然后在ProxyHandler的invoke方法中调用的。第二个参数method是由java的反射机制获得的对realMethod方法的描述,而args是realMethod
*的参数列表(我这里只用了一个realMthod方法做个代表,还可以是其它类的其它方法)
**/
// TODO Auto-generated method stub System.out.println("代理前的处理操作"); System.out.println("调用真实主题的方法");
/**
*用反射机制调用了realMethod方法
**/ method.invoke(subject, args); System.out.println("代理后的处理操作"); return null; } }
/** *客户端 **/ package dproxy; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub
/**
*创建真是主题
**/ Subject realSubject = new RealSubject();
/**
*创建代理处理器
**/ ProxyHandler handler = new ProxyHandler(realSubject);
/**
*动态的创建代理对象
*前面提到额这个动态创建的代理对象动态的实现了Subject接口。
**/
/**
*三个参数,第一个是真实主题的类加载器,第二个是真实主题的接口,就是通过第二个参数来使动态生成的代理类有和Subject一样的接口,第三个参数是代理处理器对象
*proxy会将对RealSubject对象中subjectMethod方法的调用委托给这个handler,这个handler会在调用前后做处理
**/ Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass() .getClassLoader(), realSubject.getClass().getInterfaces(), handler);
/**
*调用动态创建的代理对象的动态生成的subjectMethod方法
**/ proxy.subjectMethod(3, 5); } }
标签:
原文地址:http://www.cnblogs.com/zhoutong/p/5363916.html