码迷,mamicode.com
首页 > Web开发 > 详细

Web项目中静态代理和动态代理为基础的面向切面编程AOP

时间:2015-04-02 01:27:10      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:aop   代理   动态代理   面向切面编程   struts2   

本来每天更新的,我一般喜欢夜里过了十二点的时候发文章,结果难道是愚人节吗?学校的网也很有意思,断了,把我给耍了。。。好吧…开始今天的话题AOP。AOP太重要了,所以放到第二篇文章来谈这个话题,AOP是Spring中的重要概念。如果这个不理解Web开发中的三大框架的原理,那就呵呵了。时常听到同学和网友议论Web程序员大部分时间都是在考皮XML配置,我当时听到也是醉了,所以我要用心学习Web,其实这里面蕴含的设计模式、算法、架构思想在源码中体现的淋漓尽致啊,一个大宝库竟然视而不见可惜了。下面就一起品味…

1.静态代理

不要被这个设计模式高大上的名字给吓到了,其实静态代理还是挺容易理解的,用生活场景来理解静态代理就是:托人办事。假如一个公司想办一场演唱会,要找明星去哪找呢?明星的经纪人啊,明星哪有时间来和公司谈啊。所以这个经纪人就是静态代理中的重要角色。来看一张UML图,看看这其中的道理:
技术分享
其中Target可以理解为明星,TargetInterface可以理解为明星出场延长的标准,TargetProxy可以理解为经纪人。经纪人按照明星出场的标准和公司谈价格和其他事项等等。

将以上的思想用到Web中假如有这样一个场景:删除或者修改用户信息,在这个过程中需要开启事务。用静态代理模拟这个场景。
技术分享
这次的代理对象就变成了UserDAOImpl了,而UserDAOProxy就成了上面的经纪人了(代理)。
具体代码:GitHub
其实说到这里静态代理还是有很大的缺点的就是如果明星多了,我的经纪人成倍的增长,这个时候代码量太大了。为了克服这个问题才有动态代理的产生。

2.动态代理

静态代理可以说是动态代理的通俗版,动态代理要解决明星多了,经纪人(代理)增多的现象,同时优化代码的效率。思想是差不多的,关键在用代码实现的时候差距还是挺大的。动态代理在Java中一般有JDK代理(JDK本身提供的功能)、Cglib代理、AspectJ等。
具体代码实现看这里 。下面将和静态代理的区别拉出来:

public class ProxyInterceptor implements InvocationHandler {
    //代理目标
    private Object target ;

    //引入事务
    private Transaction tx ;

    public ProxyInterceptor(Object target,Transaction tx) {
        this.target = target ;
        this.tx =  tx ;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //开启事务
        this.tx.beginTransaction(); 

        method.invoke(target, args);

        //提交事务
        this.tx.commitTransaction();
        return null;
    }

}

其中private Object target ;声明为Object类型表示可以接受任何类型的代理对象(各种各样的明星)这样就解决了,动态代理中的固定代理对象的问题。同时代理(经纪人)都要实现一个接口InvocationHandler 这个接口是干嘛的呢?按照意思理解就是事件的处理者,然后重写接口中的invoke方法,且不管方法中的参数是什么,在这里理解为代理处理事务的重要方法。业务都在这个方法中进行调用。就可以实现了。这样动态代理就解决了应对代理对象多样性的问题。那么什么是AOP 呢?

3.面向切面编程的AOP

什么是AOP呢?有了上面代理的基础用一个例子就可以讲解什么是面向切面编程AOP了。案例背景:现在要取钱,取钱的过程之前ATM机器要开启日志功能、事务功能、安全性检查等等。代码在这里。下面看最重要的代理对象:

package org.kylin.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * @author UniKyln
 * @date 下午11:30:19 2015年3月31日
 * @blog:http://blog.csdn.net/unikylin
 * @github:https://github.com/unikylin/
 * @description 动态代理类
 */
public class DrawManagerProxy implements InvocationHandler {

    //代理目标类
    private Object target ; 

    //面向切面编程中的各种切面
    private Logger logger ;
    private Security security ;
    private Transaction tx ;

    public DrawManagerProxy(Object target,Logger logger,Security security,Transaction tx) {
        this.target = target ;
        this.logger = logger ;
        this.security = security ;
        this.tx = tx ;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //启动日志
        this.logger.logger();

        //启动事务
        this.tx.beginTransaction();

        //启动安全性检查
        this.security.checkSecurity();

        //取钱
        method.invoke(target, args);

        //提交事务
        this.tx.commitTransaction();

        return null;
    }   
}

在取钱之前启动了日志、开启事务,然后提交事务。可以用下面一个图来理解这个过程是如何发生的?
技术分享
上一篇文章已经提到这个图了。可以理解执行方法之前的日志记录、事务、安全性框架都是AOP中的切面,而AOP中的通知可以理解为是事务中的开启事务、提交事务这两个方法(切面中的方法可以理解为通知)。所以可以发现事务、日志、安全性框架和取钱完全是没有耦合的,完全是靠代理类来实现业务的。在实际的开发中每个人开发每个人的功能,类似于安全性框架的开发可以独立开发,及时以后去取钱之后需要打印小票,也可以增加一个切面实现这个功能。然后用AOP切面的思想将这些整合在一起形成一个完整的程序。

4.Struts2应用的AOP设计思想

先来看看Struts2的总体架构图:
技术分享

从图中可以发现很多的Interceptor,并且这些拦截器在Struts2中地位非常重要,这些拦截器就可以理解为切面,而ActionProxy就相当于代理将这些拦截器和目标方法联系到一起。事实上Struts2的拦截器设计就是采用AOP实现的,而且Struts2和Spring整合的时候异常的处理和拦截也是使用AOP思想实现的。AOP已经深入到框架的核心设计理念中了。今天就讲这么多吧,下一节谈谈Servlet并且如何用Servlet原生API写一个小小的类似于Struts2的框架,简化web开发中遇到的问题。


非常高兴和大家交流学习
自由转载,创意许可,请注明文章来源,来自这里
(http://blog.csdn.net/unikylin)

Web项目中静态代理和动态代理为基础的面向切面编程AOP

标签:aop   代理   动态代理   面向切面编程   struts2   

原文地址:http://blog.csdn.net/unikylin/article/details/44816407

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!