Spring AOP实践

小米手头上有个任务,需要在做某个业务之前做下鉴权。小米心想这个任务简单,只需要在原来的代码中加上鉴权的处理就可以了。

原来的代码是这样的:

 

package main.java;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public interface BusinessTrans
{
    void doIt();
}


 

package main.java.impl;

import main.java.BusinessTrans;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class BusinessTransImpl implements BusinessTrans
{
    /**
     * 需求:希望在执行这个方法前,做一个Id鉴权
     * @param name
     */
    public void doIt()
    {
        System.out.println("excute immediatly");
    }
}

 

这样只要在原来代码实现中加上鉴权的方法就行了。

package main.java.impl;

import main.java.BusinessTrans;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class BusinessTransImpl implements BusinessTrans
{
    /**
     * 需求:希望在执行这个方法前,做一个Id鉴权
     * @param name
     */
    public void doIt()
    {
        if (haveNoPopedom())
        {
            return;
        }
        
        System.out.println("excute immediatly");
    }
    
    private boolean haveNoPopedom()
    {
        return false;
    }
}

 

这样小米舒舒服服的过了一个迭代,功能实在太简单了,三下五除二就搞定了,过了一个迭代,老大只会小米说,上一轮的功能又有点新的需求。小米心想这样简单的功能点一人天就可以搞定了,这一轮还可以做点别的东西。看了一下规格,一下就蒙了,凡是实现这个接口的都需要做鉴权。。。小米心中一声次奥想起了。

小米默默的将所有实现这个接口的类全部做了修改,然后测试了所有的功能,ok了。心想:靠,这么简单的功能,代码都是一样的,竟然花了我这么长时间。

迭代快接近尾声了,小米又没有时间做点别的了。。。。

 

很快下个迭代有开始了,老大又找小米,说这个功能又有点需求,小米赶紧看了下,心想千万不要和上次来一样的变态需求。看完后心凉了一般,需求是这样的,在做完doIt后,在做一下其他的事,同样是实现该死的接口的所有类。这一回,小米受不了了,他决定和同事们讨论下这个到底应该怎么玩?

 

同事A说:其实不需要修改原来的代码,在原来的实现类上面包一层,在这个包的一层中实现鉴权等其他事。

 

package main.java.impl;

import main.java.BusinessTrans;
import main.java.logger.Level;
import main.java.logger.Logger;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class BusinessTransProxy implements BusinessTrans
{
    private BusinessTrans businessTrans;
    
    public BusinessTransProxy(BusinessTrans businessTrans)
    {
        this.businessTrans = businessTrans;
    }
    
    public void doIt()
    {
        Logger.logging(Level.INFO, "before excute doIt");
        
        businessTrans.doIt();
        
        Logger.logging(Level.INFO, "after excute doIt");
    }
}


这样凡是实现这个接口的所有的类就可以通过这个类,实现增加鉴权等一些列的功能。小米听到这个想法后,顿时觉得自己之前做的全部都是体力活。一阵欢喜之后,老大突然提出了一个问题:

如果同样有一个接口,含有一个doIt的方法,同样也需要做这样事呢?

同事B立马说道,“我再写一个这样的Proxy类实现他就行了嘛,这个方法果然好用”。

“那如果有一百个这样的接口都需要做这样的事呢?”

“这个,这个。。。。写一百个这个实现?”

“那还不是一个体力活?”

小米心想,“老大就喜欢给大家泼冷水,有一百个的时候再说嘛!”但是小米已经意识到肯定还有其他的一些方法。

 

其实现在的Jdk中提供了一个API   java.lang.reflect.InvocationHandler的类.。这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事。

 

/*
 * 文 件 名:  DynaProxyBusinessTrans.java
 * 版    权:   * 描    述:  <描述>
 * 修 改 人:  cKF54238
 * 修改时间:  Apr 1, 2013
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package main.java.dynaproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import main.java.logger.Level;
import main.java.logger.Logger;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class DynaProxyBusinessTrans implements InvocationHandler
{
    
    /**
     ** 要处理的对象(也就是我们要在方法的前后加上业务逻辑的对象)
     */
    private Object delegate;
    
    public Object bind(Object delegate)
    {
        this.delegate = delegate;
        return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(),
                this.delegate.getClass().getInterfaces(),
                this);
        
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        Object result = null;
        
        try
        {
            //执行原来的方法之前记录日志
            Logger.logging(Level.DEBUGE, method.getName() + " Method start .");
            
            result = method.invoke(this.delegate, args);
            
            //执行原来的方法之前记录日志
            Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
            
        }
        catch (Exception e)
        {
            
        }
        return result;
    }
}

 

/*
 * 文 件 名:  AOPTest.java
 * 版    权:  
 * 描    述:  <描述>
 * 修 改 人:  cKF54238
 * 修改时间:  Apr 1, 2013
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package main.java.test;

import main.java.BusinessTrans;
import main.java.dynaproxy.DynaProxyBusinessTrans;
import main.java.impl.BusinessTransImpl;

/**
 * <一句话功能简述>
 * <功能详细描述>
 * 
 * @author  cKF54238
 * @version  [版本号, Apr 1, 2013]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class AOPTest
{
    /**
     * test
     * @param args [参数说明]
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
        //        BusinessTrans businessTrans = new BusinessTransProxy(
        //                new BusinessTransImpl());
        //        
        //        businessTrans.doIt();
        //        
        //        BusinessTrans otherBusinessTrans = new BusinessTransProxy(
        //                new BusinessTransOtherImpl());
        //        
        //        otherBusinessTrans.doIt();
        
        BusinessTrans BusinessTrans = (BusinessTrans) new DynaProxyBusinessTrans().bind(new BusinessTransImpl());
        
        BusinessTrans.doIt();
    }
}


这样不管是什么接口,都可以这么玩了。

小米看完这些后,高高兴兴的全部都回滚了,然后使用新学的这一招去修改了。可想而知,他仅仅花了一小会的时间就将代码全部搞好,调测完,真是太爽了。

 

 

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值