AOP面向切面编程 (调用前, 调用时, 调用后, 出现异常时) 示例

AOP面向切面编程

SUN_DEMON (sudemon@163.com) www.egemmer.cn www.gemsuit.cn 2007/11/17

    接触Spring的AOP编程已经有一段时间了,  昨天看过Spring的源代码, 对大师的AOP实现很激动, 于是自己写了一 

   个实现4个时段拦截的示例代码.

本代码使用Java编写.

编写之前

  • 你必须了解Proxy (代理)
  • 理解反射机制

开始编写

清单1 MethodInvocation

 

package org.sy.aop.framework;

import java.lang.reflect.Method;

public   class  MethodInvocation  {
// 代理对象
    private Object proxy;
// 方法
    private Method method;
// 参数
    private Object[] args;
// 结果
    private Object result;
// 异常
    private Throwable exception;
/**
 * 方法调用
 
*/

    
public MethodInvocation(Object proxy, Method method, Object[] args,
            Object result, Throwable exception) 
{
        
this.proxy = proxy;
        
this.method = method;
        
this.args = args;
        
this.result = result;
        
this.exception = exception;
    }


    
public Object process() throws Throwable {
        
return method.invoke(proxy, args);
    }


    
public Throwable getException() {
        
return exception;
    }


    
public void setException(Throwable exception) {
        
this.exception = exception;
    }


    
public Method getMethod() {
        
return method;
    }


    
public void setMethod(Method method) {
        
this.method = method;
    }


    
public Object getProxy() {
        
return proxy;
    }


    
public void setProxy(Object proxy) {
        
this.proxy = proxy;
    }


    
public Object getResult() {
        
return result;
    }


    
public void setResult(Object result) {
        
this.result = result;
    }


    
public Object[] getArguments() {
        
return args;
    }


    
public void setArguments(Object[] args) {
        
this.args = args;
    }

}

 

清单2 BeforeAdvice

 

package  org.sy.aop.advice;

import  org.sy.aop.framework.MethodInvocation;

public   interface  BeforeAdvice  {
    
public abstract void beforeInvoke(MethodInvocation invocation)
            
throws Throwable;
}

 

清单3 AfterAdvice

 

package  org.sy.aop.advice;

import  org.sy.aop.framework.MethodInvocation;

public   interface  AfterAdvice  {
    
public abstract void afterInvoke(MethodInvocation invocation)
            
throws Throwable;
}

 

清单4 AroundAdvice

 

package  org.sy.aop.advice;

import  org.sy.aop.framework.MethodInvocation;

public   interface  AroundAdvice  {
    
public abstract Object invokeProcess(MethodInvocation invocation)
            
throws Throwable;
}

 

清单5 ThrowsAdvice

 

package  org.sy.aop.advice;

import  org.sy.aop.framework.MethodInvocation;

public   interface  ThrowsAdvice  {
    
public abstract void afterThrowing(MethodInvocation invocation);
}

 

清单6 AOPProcess

 

package  org.sy.aop;

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

import  org.sy.aop.advice.AfterAdvice;
import  org.sy.aop.advice.AroundAdvice;
import  org.sy.aop.advice.BeforeAdvice;
import  org.sy.aop.advice.ThrowsAdvice;
import  org.sy.aop.framework.MethodInvocation;

/**
 * 
 * 动态AOP
 * 
 * 
@author SUN_Demon
 * @project proxy
 * @date 2007-11-16
 
*/

public   class  AOPProcess  implements  InvocationHandler  {

    
private Object terget;

    
private AroundAdvice aroundIntercetpor;

    
private AfterAdvice afterIntercetpor;

    
private BeforeAdvice beforeIntercetpor;

    
private ThrowsAdvice throwsIntercetpor;

    
public AfterAdvice getAfterIntercetpor() {
        
return afterIntercetpor;
    }


    
public void setAfterIntercetpor(AfterAdvice afterIntercetpor) {
        
this.afterIntercetpor = afterIntercetpor;
    }


    
public AroundAdvice getAroundIntercetpor() {
        
return aroundIntercetpor;
    }


    
public void setAroundIntercetpor(AroundAdvice aroundIntercetpor) {
        
this.aroundIntercetpor = aroundIntercetpor;
    }


    
public BeforeAdvice getBeforeIntercetpor() {
        
return beforeIntercetpor;
    }


    
public void setBeforeIntercetpor(BeforeAdvice beforeIntercetpor) {
        
this.beforeIntercetpor = beforeIntercetpor;
    }


    
public Object getTerget() {
        
return terget;
    }


    
public void setTerget(Object terget) {
        
this.terget = terget;
    }


    
public ThrowsAdvice getThrowsIntercetpor() {
        
return throwsIntercetpor;
    }


    
public void setThrowsIntercetpor(ThrowsAdvice throwsIntercetpor) {
        
this.throwsIntercetpor = throwsIntercetpor;
    }


    
/**
     * 创建代理实例
     * 
     * 
@param terget -
     *            代理对象
     * 
@return 代理实例
     
*/

    
public Object bind(Object terget) {
        
this.terget = terget;
        
return Proxy.newProxyInstance(terget.getClass().getClassLoader(),
                terget.getClass().getInterfaces(), 
this);
    }


    
/**
     * 在Invoke方法中, 在调用过程中作出相应的处理.
     
*/

    
public Object invoke(Object proxy, Method method, Object[] args)
            
throws Throwable {
        Object result 
= null;
        Throwable exception 
= null;
        MethodInvocation invocation 
= new MethodInvocation(proxy, method, args,
                result, exception);
        
try {
            
// 调用方法前拦截
            if (this.beforeIntercetpor != null)
                
this.beforeIntercetpor.beforeInvoke(invocation);
            
// 调用方法时拦截
            if (this.aroundIntercetpor != null)
                
this.aroundIntercetpor.invokeProcess(invocation);
            
else
                invocation.setResult(invocation.process());
            
// 调用方法后拦截
            if (this.afterIntercetpor != null)
                
this.afterIntercetpor.afterInvoke(invocation);
        }
 catch (Exception e) {
            
// 调用方法出现异常后拦截
            e.printStackTrace();
            
if (this.throwsIntercetpor != null)
                
this.throwsIntercetpor.afterThrowing(invocation);
        }


        
return invocation.getResult();
    }

}

 

小结

AfterAdvice, BeforeAdvice, AroundAdvice, ThrowsAdvice 都是处理器接口, 使用这个示例之前, 先必须提供处理器实现类. AfterAdvice 是调用之前, BeforeAdvice 是调用之后, AroundAdvice 是调用时, ThrowsAdvice 是调用出现异常时. 使用AOPProcess 类之前, 需要相应的处理器实现类以及代理目标对象, 然后调用bind方法, 创建代理对象.

<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值