模拟spring - 动手写一个spring AOP(一)

2014-11-23 22:09:35 · 作者: · 浏览: 3

一、前言

AOP (Aspect Oriented Programing) - 面向切面编程,它主要用于日志记录、性能分析、安全控制、事务处理、异常处理等方面。

AOP主要使用JDK的反射和动态代理,AOP代理其实是由AOP框架动态生成的一个对象,该对象可作为目标对象使用,AOP代理包含了目标对象的全部方法,但AOP代理的方法与目标对象的方法存在差异:AOP方法在特定切入点添加了增强处理,并回调了目标对象的方法。

二、实现细节

下面这个例子利用AOP来实现日志记录:

附上一张类的结构图,该例子需要导入dom4j.jar

\

①业务逻辑接口

/**
 * 业务逻辑类接口
 * @author zhangjim
 */
public interface BusinessService {
	/**
	 * 处理业务
	 */
	public void process();
}
② 业务逻辑实现

/**
 * 业务逻辑对象实现类
 * @author zhangjim
 */
public class BusinessServiceImpl implements BusinessService {
	/**
	 * 处理业务
	 */
	public void process() {
		System.out.println(process business logic...);
	}
}
③ 通知类接口

/**
 * 通知类接口
 * @author zhangjim
 */
public interface Advisor {
	/**
	 * 所做的操作
	 */
	public void doInAdvisor(Object proxy, Method method, Object[] args);
}
④ 方法的前置通知

import java.lang.reflect.Method;

/**
 * 方法前置通知,它完成方法的前置操作
 * @author zhangjim
 */
public class BeforeMethodAdvisor implements Advisor {
	/**
	 * 在方法执行前所进行的操作
	 */
	public void doInAdvisor(Object proxy, Method method, Object[] args) {
		System.out.println(before process... );
	}
}
⑤ 方法的后置通知

/**
 * 方法的后置通知,它完成方法的后置操作
 * @author zhangjim
 */
public class AfterMethodAdvisor implements Advisor {
	/**
	 * 在方法执行后所进行的操作
	 */
	public void doInAdvisor(Object proxy, Method method, Object[] args) {
		System.out.println(after process...);
	}
}
⑥ AOP处理器

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.zdp.advisor.Advisor;

/**
 * AOP处理器
 * @author zhangjim
 */
public class AopHandler implements InvocationHandler {
	private Object target; // 需要代理的目标对象
	Advisor beforeAdvisor; // 方法前置通知
	Advisor afterAdvisor; // 方法后置通知

	/**
	 * 设置代理目标对象,并生成动态代理对象.
	 * @param target 代理目标对象
	 * @return 返回动态代理对象
	 */
	public Object setObject(Object target) {
		this.target = target; // 设置代理目标对象 
		Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); // 根据代理目标对象生成动态代理对象
		return proxy;
	}

	/**
	 * 若定义了前置处理,则在方法执行前执行前置处理, 若定义了后置处理,则在方法调用后调用后置处理.
	 * 
	 * @param proxy 代理对象
	 * @param method 调用的业务方法
	 * @param args 方法的参数
	 * @return 返回结果信息
	 * @throws Throwable
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if (beforeAdvisor != null) { 
			beforeAdvisor.doInAdvisor(proxy, method, args); // 进行业务方法的前置处理
		}
		method.invoke(target, args); // 执行业务方法
		if (afterAdvisor != null) {
			afterAdvisor.doInAdvisor(proxy, method, args); // 进行业务方法的后置处理
		}
		return null; // 返回结果对象
	}

	/**
	 * 设置方法的前置通知
	 * @param advisor 方法的前置通知
	 */
	public void setBeforeAdvisor(Advisor advisor) {
		this.beforeAdvisor = advisor;
	}

	/**
	 * 设置方法的后置通知
	 * @param advisor 方法的后置通知
	 */
	public void setAfterAdvisor(Advisor advisor) {
		this.afterAdvisor = advisor;
	}
}
⑦ Bean工厂类

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.zdp.advisor.Advisor;

/**
 * Bean工厂类
 * @author zhangjim
 */
public class BeanFactory {
	private Map
  
    beansMap = new HashMap
   
    (); /** * Bean工厂的初始化 */ public void init(String xml) { try { SAXReader reader = new SAXReader(); ClassLoa