静态代理(static proxy)和动态代理(dynamic proxy)

两种类型AOP:静态AOP和动态AOP。

静态代理:
代理对象与被代理对象必须实现同一个接口。

demo:
  1. packagecn.partner4java.proxy.staticproxy;
  2. /**
  3. * 静态代理,统一接口
  4. * @author partner4java
  5. *
  6. */
  7. publicinterfaceIHello {
  8. /**
  9. * 可以带来的统一方法
  10. * @param name
  11. */
  12. publicvoidhello(String name);
  13. }
  1. packagecn.partner4java.proxy.staticproxy;
  2. /**
  3. * 被代理的对象,需要借助代理对象加入日志
  4. * @author partner4java
  5. *
  6. */
  7. publicclassHelloSpeakerimplementsIHello {
  8. publicvoidhello(String name) {
  9. System.out.println("Hello "+ name);
  10. }
  11. }
  1. packagecn.partner4java.proxy.staticproxy;
  2. /**
  3. * 代理对象,给被代理对象添加日志
  4. */
  5. publicclassHelloProxyimplementsIHello {
  6. privateIHello iHello;
  7. publicHelloProxy(IHello iHello) {
  8. super();
  9. this.iHello = iHello;
  10. }
  11. publicvoidhello(String name) {
  12. System.out.println("记录日志");
  13. iHello.hello(name);
  14. }
  15. }
  1. packagecn.partner4java.proxy.staticproxy;
  2. /**
  3. * 调用
  4. * @author partner4java
  5. *
  6. */
  7. publicclassProxyDemo {
  8. publicstaticvoidmain(String[] args) {
  9. IHello iHello =newHelloProxy(newHelloSpeaker());
  10. iHello.hello("long");
  11. }
  12. }





动态代理:
动态代理区别于静态带来实现的地方在于织入过程是在运行时动态进行的。自己实现一般实现java.lang.reflect.InvocationHandler接口。
例子:
  1. packagecn.partner4java.proxy.dynamicproxy;
  2. publicinterfaceIHello {
  3. publicvoidhello(String name);
  4. }
  1. packagecn.partner4java.proxy.dynamicproxy;
  2. /**
  3. * 被代理的对象,需要借助代理对象加入日志
  4. * @author partner4java
  5. *
  6. */
  7. publicclassHelloSpeakerimplementsIHello {
  8. publicvoidhello(String name) {
  9. System.out.println("Hello "+ name);
  10. }
  11. }
  1. packagecn.partner4java.proxy.dynamicproxy;
  2. importjava.lang.reflect.InvocationHandler;
  3. importjava.lang.reflect.Method;
  4. importjava.lang.reflect.Proxy;
  5. /**
  6. * 动态代理对象
  7. * @author partner4java
  8. *
  9. */
  10. publicclassLogHandlerimplementsInvocationHandler {
  11. privateObject delegate;
  12. publicObject bind(Object delegate){
  13. this.delegate = delegate;
  14. returnProxy.newProxyInstance(delegate.getClass().getClassLoader(),
  15. delegate.getClass().getInterfaces(),this);
  16. }
  17. /**
  18. * 代理对象,这里面还可以改变原有的方法
  19. */
  20. publicObject invoke(Object proxy, Method method, Object[] args)
  21. throwsThrowable {
  22. Object result =null;
  23. try{
  24. System.out.println("添加日志");
  25. result = method.invoke(delegate, args);
  26. }catch(Exception e) {
  27. e.printStackTrace();
  28. }
  29. returnnull;
  30. }
  31. }
  1. packagecn.partner4java.proxy.dynamicproxy;
  2. /**
  3. * 测试
  4. * @author partner4java
  5. *
  6. */
  7. publicclassProxyDemo {
  8. publicstaticvoidmain(String[] args) {
  9. LogHandler logHandler =newLogHandler();
  10. IHello iHello = (IHello) logHandler.bind(newHelloSpeaker());
  11. iHello.hello("long");
  12. }
  13. }


------------------------------------------------------------------


利用ProxyFactory连接CGLIB简单实现AOP:
加入包aopalliance.jar\cglib-nodep-2.1_3.jar
demo:
  1. packagecn.partner4java.proxy.proxyfactory;
  2. /**
  3. * 被代理的对象
  4. * @author partner4java
  5. *
  6. */
  7. publicclassMessageWriter {
  8. publicvoidwriteMessage(){
  9. System.out.println("world!");
  10. }
  11. }
  1. packagecn.partner4java.proxy.proxyfactory;
  2. importorg.aopalliance.intercept.MethodInterceptor;
  3. importorg.aopalliance.intercept.MethodInvocation;
  4. /**
  5. * 装饰者<br/>
  6. * MethodInterceptor接口是对方法调用连接点实现包围通知的AOP联盟标准接口
  7. * @author partner4java
  8. *
  9. */
  10. publicclassMessageDecoratorimplementsMethodInterceptor{
  11. publicObject invoke(MethodInvocation invocation)throwsThrowable {
  12. System.out.print("Hello ");
  13. Object retVal = invocation.proceed();
  14. returnretVal;
  15. }
  16. }
  1. packagecn.partner4java.proxy.proxyfactory;
  2. importorg.springframework.aop.framework.ProxyFactory;
  3. /**
  4. * 调用组装
  5. * 这里最重要的部分是我们使用ProxyFactory来创建一个目标对象代理,同时织入通知
  6. * @author partner4java
  7. *
  8. */
  9. publicclassHelloWorldWeaver {
  10. publicstaticvoidmain(String[] args) {
  11. //目标
  12. MessageWriter target =newMessageWriter();
  13. //create the proxy
  14. ProxyFactory proxyFactory =newProxyFactory();
  15. proxyFactory.addAdvice(newMessageDecorator());
  16. proxyFactory.setTarget(target);
  17. //获取返回被代理的目标
  18. MessageWriter proxy = (MessageWriter) proxyFactory.getProxy();
  19. target.writeMessage();
  20. System.out.println("---");
  21. proxy.writeMessage();
  22. //后台打印:
  23. //world!
  24. //---
  25. //World world!
  26. }
  27. }







------------------------------------------------------------------

代理
1.代理解决什么问题,为已存在的目标类的方法增加一些系统功能。如果采用工厂模式和配置文件进行管理,以后也很容易就可以去掉增加的功能。
2.静态代理类的工作原理,太多静态代理类,还有什么意思?jvm可以帮我们创建代理类,这就是动态代理类。
3.让jvm创建动态代理类,我们需要给它提供哪些信息?
让jvm帮我们创建一个类,我们需要为它提供哪些信息呢?a.有哪些方法,即告诉它实现哪些接口;b.产生的类必须有个妈妈,即类加载器对象;c.它生成的类中的方法的代码是怎样的,需我告诉它,我把我的代码写在一个约定好了接口的对象的方法中,把对象传给它,它调用我的方法,即相当于插入了我的代码。
4.写程序的步骤:
1). 快速演示动态代理的效果
  1. privatestaticvoidtest1() {
  2. Collection proxy = (Collection)Proxy.newProxyInstance(
  3. ProxyTest.class.getClassLoader(),//first parameter
  4. newClass[]{Collection.class} ,//second parameter
  5. newInvocationHandler(){//third parameter
  6. Vector target =newVector();
  7. @Override
  8. publicObject invoke(Object proxy, Method method,
  9. Object[] args)throwsThrowable {
  10. // TODO Auto-generated method stub
  11. System.out.println("begin "+ method.getName());
  12. Object retval = method.invoke(target, args);
  13. System.out.println("end"+ method.getName());
  14. returnretval;
  15. }
  16. }
  17. );
  18. //---
  19. System.out.println(proxy.getClass().getName());
  20. proxy.add("abc");
  21. proxy.add("xyz");
  22. System.out.println(proxy.size());
  23. //---
  24. }


2).可以接收外面传入的目标
  1. privatestaticvoidtest2() {
  2. Vector v =newVector();
  3. classMyInvocationHandlerimplementsInvocationHandler
  4. {
  5. Collection target =null;
  6. publicMyInvocationHandler(){}
  7. publicMyInvocationHandler(Collection target){this.target = target;}
  8. @Override
  9. publicObject invoke(Object proxy, Method method,
  10. Object[] args)throwsThrowable {
  11. // TODO Auto-generated method stub
  12. System.out.println("begin "+ method.getName());
  13. Object retval = method.invoke(target, args);
  14. System.out.println("end"+ method.getName());
  15. returnretval;
  16. }
  17. }
  18. Collection proxy1 = (Collection)Proxy.newProxyInstance(
  19. ProxyTest.class.getClassLoader(),
  20. newClass[]{Collection.class} ,
  21. newMyInvocationHandler(v));
  22. System.out.println(proxy1.getClass().getName());
  23. proxy1.add("abc");
  24. proxy1.add("xyz");
  25. System.out.println(proxy1.size());
  26. }

3).最优雅的方式,接收目标同时返回代理,让调用者更懒惰,更方便,调用者甚至不用接触任何代理的API。
  1. privatestaticvoidtest3() {
  2. Vector v =newVector();
  3. classMyInvocationHandlerimplementsInvocationHandler
  4. {
  5. Collection target =null;
  6. publicCollection bind(Collection target)
  7. {
  8. this.target = target;
  9. Collection proxy1 = (Collection)Proxy.newProxyInstance(
  10. ProxyTest.class.getClassLoader(),
  11. newClass[]{Collection.class} ,
  12. this);
  13. returnproxy1;
  14. }
  15. @Override
  16. publicObject invoke(Object proxy, Method method,
  17. Object[] args)throwsThrowable {
  18. // TODO Auto-generated method stub
  19. System.out.println("begin "+ method.getName());
  20. Object retval = method.invoke(target, args);
  21. System.out.println("end"+ method.getName());
  22. returnretval;
  23. }
  24. }
  25. MyInvocationHandler handler =newMyInvocationHandler();
  26. Collection proxy1 = handler.bind(v);
  27. System.out.println(proxy1.getClass().getName());
  28. proxy1.add("abc");
  29. proxy1.add("xyz");
  30. System.out.println(proxy1.size());
  31. }


一点小心得:静态方法中也可以定义内部类,只是内部类中不能方法外部类的成员变量。

  1. iterface Foo
  2. {
  3. doTest();
  4. }
  5. Class xxx = Proxy.getProxyClass(Foo.class.getClassLoader(),Class [] {Foo.class});
  6. Proxy方法自动生成一个类的字节码,这个自动生成的类实现了Foo接口(可以实现若干接口)。生成的类有Foo接口中的所有方法和一个如下形式的构造方法:
  7. Xxx
  8. {
  9. InvocationHandler handler;
  10. publicXxx(InvocationHandler handler)
  11. {
  12. this.handler = handler;
  13. }
  14. //生成的Foo接口中的方法的运行原理
  15. doTest()
  16. {
  17. handler.invoke(this,newMethod("doTest"),null)
  18. }
  19. }
  20. 创建代理类的实例对象的语法解释
  21. clsProxy.getConstructor(Class []{InvocationHandlre.class}).newInstance(xhandlder);
  22. Invocationhandler接口的实现示意:
  23. classMyInvocationHandler impments InvocationHandler
  24. {
  25. invoke(Object proxy,Method method,Object[] args)
  26. {
  27. log.info();
  28. Mehtod.invoke(yyy);
  29. }
  30. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值