Spring AOP 最终版实现

Posted 邱慕夏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP 最终版实现相关的知识,希望对你有一定的参考价值。

引言


Spring AOP 是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。


其实,我们在系统中通过AOP实现权限、日志、异常等等非业务服务横切到我们的业务服务中,并且在不修改代码的形式,通常情况要是需要修改XML文件的,而且,当我们修改了非业务服务的时候,所有的业务服务中的代码都会修改。


代码实现:


目录:



AOPClient:


package com.tgb.client;

import com.tgb.config.ClassPathXmlApplicationContext;
import com.tgb.config.ContainerBeans;
import com.tgb.dao.UserDao;
import com.tgb.domain.User;

/**
 * AOP效果测试
* @ClassName: AopClientTest 
* @Description: 
* @author [qmx] 
* @date 
*
 */
public class AopClient {

	public static void main(String[] args) throws Exception {

		ContainerBeans factory = new ClassPathXmlApplicationContext();

		User user = new User();
		user.setUserName("hanyankun");

		Object proxyObject = factory.getBean("UserDao");
		UserDao userDao = (UserDao) proxyObject;

		System.out.println("----启用aop一");
		
//		userDao.before(user);
		userDao.update(user);
		userDao.save(user);
	

		//

	}
}

ClientTest:


package com.tgb.client;

import com.tgb.config.ClassPathXmlApplicationContext;
import com.tgb.config.ContainerBeans;
import com.tgb.dao.StudentDao;
import com.tgb.dao.TeacherDao;
import com.tgb.daoImpl.StudentDaoImpl;
import com.tgb.domain.User;

/**
 * 容器效果测试,测试增删对象
* @ClassName: ClientTest 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author [qmx] 
* @date  
*
 */
public class ClientTest {

	public static void main(String[] args) throws Exception {

		ContainerBeans containerBeans = new ClassPathXmlApplicationContext();// new
																				// 为
																				// 装配容器过程

		User user = new User();
		user.setUserName("hanyankun"); // 参数设置

		containerBeans.printAllbeanId();
		System.out.println("\\n");

		//增加对象
		StudentDao studentrDao = new StudentDaoImpl();
		containerBeans.put("studentDao", studentrDao);

		System.out.println("----放入对象-studentDao---");
		containerBeans.printAllbeanId();
		System.out.println("\\n");
		
		//获取添加的对象
		System.out.println("-----拿出来的studentDao-执行方法--syaName-");
		StudentDao studentrDaoBean = (StudentDao) containerBeans.getBean("studentDao");
		TeacherDao teacherDao = (TeacherDao) containerBeans.getBean("TeacherDao");
		
		teacherDao.save(user);
		studentrDaoBean.syaName();
		System.out.println("\\n");

		//删除对象测试
		System.out.println("-----删除对象TeacherDao 和 UserDao--");
		containerBeans.remove("TeacherDao");
		containerBeans.remove("UserDao");
		containerBeans.printAllbeanId();
	}

}

AspectCachBean:


package com.tgb.config;


/**
* @ClassName: AspectCachBean 
* @Description: 
* 缓存服务类,实现了对缓存的,前置,后置, 保存的方法
* @author [qmx] 
* @date 
*
 */
public class AspectCachBean {
	
	/**
	 * 
	* @Title: cacheBefore 
	* @Description: 缓存前置增强方法
	* @param @param proxy    代理参数
	* @return void    返回类型 
	* @throws
	 */
	public  void cacheBefore(Object proxy) {

		System.out.println("---这是切入 类AspectCachBean  cacheBefore()-方法--");
	}

	/**
	 * 
	* @Title: cacheAfter 
	* @Description: 缓存后置增强方法
	* @param @param proxy    返回的代理参数
	* @return void    返回类型 
	* @throws
	 */
	public static void cacheAfter(Object proxy) {
		System.out.println("---这是切入 类AspectCachBean  cacheAfter()-方法--");
	}
	
	/**
	* @Title: cacheSave 
	* @Description: 缓存保存方法 
	* @param @param proxy    代理参数
	* @return void    返回类型 
	* @throws
	 */
	public void cacheSave(Object proxy){
		System.out.println("---这是切入 类AspectCachBean  cacheSave()-方法--");
	}
}

AspectCertifiyBean:


package com.tgb.config;

/**
 * 
* @ClassName: AspectCertifiyBean 
* @Description: 认证服务类,提供了认证前, 认证后,认证保存的方法 
* @author [qmx] 
* @date 
*
 */
public class AspectCertifiyBean {

	/**
	 * 
	* @Title: certifiyBefore 
	* @Description: 认证前置增强方法
	* @param @param proxy    被代理对象的参数 
	* @return void    返回类型 
	* @throws
	 */
	public void certifiyBefore(Object proxy) {

		System.out.println("---这是切入 类AspectCertifiyBean  certifiyBefore()-方法--");
	}

	/**
	 * 
	* @Title: certifyAfter 
	* @Description: 认证后置增强方法
	* @param @param proxy    被认证对象参数
	* @return void    返回类型 
	* @throws
	 */
	public  void certifyAfter(Object proxy) {
		System.out.println("---这是切入 类AspectCertifiyBean  certifyAfter()-方法--");
	}

	/**
	 * 
	* @Title: certifySave 
	* @Description:认证保存增强方法
	* @param @param proxy   被认证对象参数
	* @return void    返回类型 
	* @throws
	 */
	public void certifySave(Object proxy) {
		System.out.println("---这是切入 类AspectCertifiyBean  certifySave()-方法--");
	}
}

ClassPathXmlApplicationContext:


package com.tgb.config;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

/**
 * 
* @ClassName: ClassPathXmlApplicationContext 
* @Description:  容器组装类, 装载 业务容器 和 服务容器。 分别将其中的 颗粒装载到各自的 beans 中
* 同时提供了对容器的增删,遍历等公共方法
* @author [qmx] 
* @date  
*
 */
public class ClassPathXmlApplicationContext implements ContainerBeans {

	// 业务容器beans
	private Map<String, Object> businessBeans = new HashMap<String, Object>();

	// 公共服务容器beans
	private Map<String, Object> aspectBeans = new HashMap<String, Object>();

	//关系集合配置
	private Map<String, Object> relationBeans = new HashMap<String, Object>();

	// 设置是否需要aop
	private boolean isAop = true;

	
	/**
	 * 
	* <p>Title: 构造函数 </p> 
	* <p>Description: 构造函数加载所有配置文件,初始化每个容器内对象</p> 
	* @throws Exception
	 */
	public ClassPathXmlApplicationContext() throws Exception {
		SAXBuilder sb = new SAXBuilder();

		// 扫描业务文档,将xml转为文档对象
		Document businessDoc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("business.xml"));

		// 扫描切入文档,将xml转为文档对象
		Document aspectDoc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("aspecbeans.xml"));

		//扫描关系文档,将xml转为文档对象
		Document reliationDoc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("relationbean.xml"));

		// 设置切面容器
		getAspectBeans(aspectDoc);

		// 设置业务容器bean
		getBusinessDoc(businessDoc);
		//关系集合设置
		getRelationBeans(reliationDoc);
	}

	/***
	 * 设置业务容器装配
	 * 
	 * @param doc
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	private void getBusinessDoc(Document businessDoc) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
			SecurityException, IllegalArgumentException, InvocationTargetException {

		Element root = businessDoc.getRootElement();//读取文档根目录
		List list = root.getChildren("bean");

		// 调用装备对象方法,装配业务对象
		putAllBeans(list, businessBeans);

	}

	/**
	 * 获取关系集合中 业务容器与切面容器的关系
	 * @param reliationDoc 
	 */
	private void getRelationBeans(Document reliationDoc) {

		Element root = reliationDoc.getRootElement(); //读取文档根目录
		Element aopElement = (Element) root.getChildren("aop").get(0); //获取aop节点信息

		isAop = Boolean.parseBoolean(aopElement.getAttributeValue("isaop")); //aop节点属性
		List aopBeforeList = root.getChildren("aspectbefore");// 前置增强节点
		List aopAfterList = root.getChildren("aspectafter");//后置增强
		//辨别增强节点是否有配置,放入bean关系容器
		if (aopBeforeList != null) {
			relationBeans.put("aspectbefore", aopBeforeList);

		}
		if (aopAfterList != null) {
			relationBeans.put("aspectafter", aopAfterList);
		}
	}

	/**
	 * 设置切入容器装配对象
	 * 
	 * @param aspectDoc 切入配置文件
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	private void getAspectBeans(Document aspectDoc) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
			SecurityException, IllegalArgumentException, InvocationTargetException {

		Element root = aspectDoc.getRootElement();
		List aspectElements = root.getChildren("aspectbean");// 读取切入配置文件
		putAllBeans(aspectElements, aspectBeans);

	}

	/**
	 * 对象装配方法
	 * 
	 * @param list
	 *            读取的配置文件
	 * @param allBeans
	 *            设置装配的容器对象
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void putAllBeans(List list, Map<String, Object> allBeans)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, NoSuchMethodException, SecurityException,
			IllegalArgumentException, InvocationTargetException {

		for (int i = 0; i < list.size(); i++) {
			//获取传入父亲节点中的每个子节点,为行element
			Element element = (Element) list.get(i);
			//获取子节点中的id属性
			String id = element.getAttributeValue("id");
			//获取子节点中的class属性
			String clazz = element.getAttributeValue("class");
			//实例化class
			Object o = Class.forName(clazz).newInstance();

			//将实例化的class放入容器
			allBeans.put(id, o);

			//for循环获取 bean中的 属性property
			for (Element propertyElement : (List<Element>) element
					.getChildren("property")) {
				//获取property属性中的name属性
				String name = propertyElement.getAttributeValue("name"); // userDAO
				
				//获取property属性中的ref属性
				String bean = propertyElement.getAttributeValue("ref"); // 
				
				//获取子属性的试题
				Object beanObject = allBeans.get(bean);// UserDAOImpl

				//调用 依赖实体中的set方法(为子实体的方法)
				String methodName = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);

				// 获取依赖注入对象的父类,如: userDaoImp 获取的为祈父类接口 userDao{eanObject.getClass().getInterfaces()[0]}
				Method m = o.getClass().getMethod(methodName, //若依赖对象没有父类接口,该方法中的参数需要修改为类本身引用
						beanObject.getClass().getInterfaces()[0]);
				m.invoke(o, beanObject); //调用o中 set方法,设置注入对象
			}

		}
	}

	/**
	 * 获取容器中指定对象
	 * 
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id) {

		//读取是否配置aop节点属性,若是返回aop代理类
		if (!isAop) {
			return businessBeans.get(id);
		}
		return new JDKDynamicProxy(businessBeans.get(id), aspectBeans, businessBeans,relationBeans)
				.getProxy();
	}

	/**
	 * 容器中放入对象
	 * 
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v) {

		return businessBeans.put(k, v);
	}

	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName() {

		Set<String> hashSet = new HashSet<String>();
		//set集合获取map中的所有值
		Set<Entry<String, Object>> entryset = businessBeans.entrySet();
		{
			//iterator获取迭代属性
			Iterator iterator = entryset.iterator();
			//while循环获取每个值
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				hashSet.add(entry.getValue().getClass().getSimpleName());
			}

		}
		for (String setType : hashSet) {
			System.out.println(setType);
		}

	}

	/**
	 * 获取容器中所有对象
	 * 
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean() {
		Map<String, Object> beanList = new HashMap<String, Object>();
		//获取得带属性
		Iterator iterator = businessBeans.entrySet().iterator();
		
		//while循环获取每个值
		while (iterator.hasNext()) {
			Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
			beanList.put(entry.getValue().getClass().getSimpleName(), entry.getValue());
		}
		return beanList;

	}

	/***
	 * 删除指定对象
	 */
	public void remove(String id) {
		businessBeans.remove(id);

	}

	/***
	 * 打印所有注入对象
	 */
	public void printAllbeanId() {
		Set<Entry<String, Object>> entryset = businessBeans.entrySet();

		Set<String> linkSet = new TreeSet<String>();
		{
			Iterator iterator = entryset.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				linkSet.add(entry.getKey());
				// System.out.println(entry.getKey());
			}

			System.out.println("容器中含有对象是" + this.size() + "个,分别是:");
			System.out.println(linkSet.toString());
			
		}

	}

	/**
	 * 获取容器中对象的个数
	 */
	public int size() {
		return businessBeans.size();
	}
}


ContainerBeans:


package com.tgb.config;

import java.util.Map;

/**
 * 
* @ClassName: ContainerBeans 
* @Description: 容器接口,提供容器公共服务方法, 增加,删除,遍历,获取对象,遍历类型,容器大小等方法
* @author [qmx] 
* @date 
*
 */
public interface ContainerBeans {
	
	/**
	 * 获取容器中指定对象
	 * 
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id);

	
	/**
	 * 容器中放入对象
	 * 
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v);

	
	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName();

	
	/**
	 * 获取容器中所有对象 返回类型 Map<string(对象类型),Object(对象)>
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean();
	
	
	/**
	 * 获取容器所有bean
	 */
	public void printAllbeanId();

	
	/**
	 * 
	* @Title: remove 
	* @Description: 删除容器指定对象
	* @param @param id    删除对象的id 
	* @return void    返回类型 
	* @throws
	 */
	public void remove(String id);

	
	/**
	 * 容器中对象的数量
	 * @return
	 */
	public int size();
}

JDKDynamicProxy:


package com.tgb.config;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.jdom.Element;

/**
 * 
* @ClassName: JDKDynamicProxy 
* @Description: AOP实现对业务容器 的增强,对业务容器中每个对象增强 服务类中的方法,根据 关系容器配置,
* 实现特性方法增强
* @author [qmx] 
* @date 
*
 */
public class JDKDynamicProxy implements InvocationHandler {

	private Object target;//被代理对象

	private Map<String, Object> aspectBeans; // 服务容器
	private Map<String, Object> businessBeans;// 业务容器
	private Map<String, Object> relationBeans;// 关系容器

	/***
	 * 
	 * @param target
	 *            被代理对象
	 * @param aspectBeans
	 *            切容器
	 * @param businessBeans
	 *            业务容器
	 * @param relationBeans
	 *            关系集合
	 */
	public JDKDynamicProxy(Object target, Map<String, Object> aspectBeans,
			Map<String, Object> businessBeans, Map<String, Object> relationBeans) {
		this.target = target;
		this.aspectBeans = aspectBeans;
		this.businessBeans = businessBeans;
		this.relationBeans = relationBeans;
	}

	/**
	* @Title: getProxy 
	* @Description: 创建被代理对象 
	* @param @return    
	* @return T    返回类型  被代理对象 类型
	* @throws
	 */
	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target
				.getClass().getInterfaces(), this);
	}

	// 回调注册切入对象方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		List beforeList = (List) relationBeans.get("aspectbefore");// 获取关系容器中的关系
		invokeAspectName(beforeList, method, args);// 调用切面类中匹配方法
		Object result = method.invoke(target, args);// 调用 被代理类本身方法

		return result;
	}

	/**
	 * 拦截方法匹配规则
	 * 
	 * @param beforeList
	 *            拦截器的所有对象
	 * @param method
	 * @param args
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void invokeAspectName(List beforeList, Method method, Object[] args)
			throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		
		//判断关系容器中是否指定了特性方法拦截,若无,则对 代理对象 执行所有服务类方法增强
		if (beforeList != null && beforeList.size() != 0) {

			for (int i = 0; i < beforeList.size(); i++) {

				Element element = (Element) beforeList.get(i);
				String aspectClass = element.getAttributeValue("aspectId");// 获取容器中切入类名称
				String aspectName = element.getAttributeValue("aspectMethod");// 执行的切入方法
				
				if (aspectBeans.get(aspectClass) == null) {
					System.out.println("未找到" + aspectClass + "切入类,请查看配置的切入类名称是否正确");
					return;
				}
				
				Class clazz = aspectBeans.get(aspectClass).getClass(); // 获取切入类
				String elementMethod = element.getAttributeValue("method");// 获取被切入类方法

				//1  关系容器中某个拦截配置,若未声明执行某个服务类中的方法,则执行所有服务类中方法,
				//2 若未指定某个拦截方法,但指定了被拦截对象的方法,则所有服务类只对该方法拦截
				//3 
				if (aspectName == null) {

					//声明了拦截某个对象方法,执行指定方法拦截
					if (method.getName() != null) {
						if (method.getName().equals(elementMethod)) {
							//,执行该服务类中所有方法
							getAllMethod(clazz, aspectClass, args);
						}

					}
					//执行所有服务类中的所有方法
					aspactAllClass(aspectClass, args == null ? new Object[1] : args);
					
				} else {
					// 声明切入方法,则执行指定切入方法
					if (method.getName().equals(elementMethod)) {
						Method jinectmethod = clazz.getMethod(aspectName, Object.class); // 反射调用切入类方法
						jinectmethod.invoke(aspectBeans.get(aspectClass),
								args == null ? new Object[1] : args);
					}
					aspactAllClass(aspectClass, args == null ? new Object[1] : args);
				}

			}

		} else {

			//默认执行所有服务类中的方法增强
			Iterator aspectClass = aspectBeans.entrySet().iterator();
			while (aspectClass.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) aspectClass.next();
				Class clazz = entry.getValue().getClass();// 获取服务类
				// 获取服务类中的所有公共方法
				Method[] methods = clazz.getDeclaredMethods();
				for (int j = 0; j < methods.length; j++) {

					// 反射获取服务类中每个方法名称,获取该服务类方法
					Method jinectmethod = clazz.getMethod(methods[j].getName(),
							Object.class);
					jinectmethod.invoke(entry.getValue(), args == null ? new Object[1]
							: args);
				}
			}
		}
	}


	/**
	 * 
	* @Title: aspactAllClass 
	* @Description: 除了自身,执行其他所有服务类中方法。
	* @param @param aspectId
	* @param @param args
	* @param @throws NoSuchMethodException
	* @param @throws SecurityException
	* @param @throws IllegalAccessException
	* @param @throws IllegalArgumentException
	* @param @throws InvocationTargetException    设定文件 
	* @return void    返回类型 
	* @throws
	 */
	public void aspactAllClass(String aspectId, Object[] args)
			throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		Iterator aspectClass = aspectBeans.entrySet().iterator();
		while (aspectClass.hasNext()) {
			Entry<String, Object> entry = (Entry<String, Object>) aspectClass.next();
			
			//
			if (!aspectId.equals(entry.getKey())) {
				Class clazz = entry.getValue().getClass();// 获取切入类
				Method[] methods = clazz.getDeclaredMethods();
				for (int j = 0; j < methods.length; j++) {
					// 反射获取服务类中每个方法名称,获取该服务类方法
					Method jinectmethod = clazz.getMethod(methods[j].getName(),
							Object.class);
					// 反射调用切入类方法
					jinectmethod.invoke(entry.getValue(), args == null ? new Object[1]
							: args);

				}
			}
		}
	}


	/**
	 * 
	* @Title: getAllMethod 
	* @Description:  执行某个服务类中的所有方法,
	* @param @param clazz 服务类
	* @param @param aspectClass	aop关系集合中设定执行 拦截的方法
	* @param @param args 被拦截对象的参数
	* @param @throws IllegalAccessException
	* @param @throws IllegalArgumentException
	* @param @throws InvocationTargetException
	* @param @throws NoSuchMethodException
	* @param @throws SecurityException    设定文件 
	* @return void    返回类型 
	* @throws
	 */
	public void getAllMethod(Class clazz, String aspectClass, Object[] args)
			throws IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchMethodException, SecurityException {
		
		// 获取服务类中的所有公共方法
		Method[] methods = clazz.getDeclaredMethods();
		for (int j = 0; j < methods.length; j++) {

			// 反射获取服务类中每个方法名称,获取该服务类方法
			Method jinectmethod = clazz.getMethod(methods[j].getName(), Object.class);
			// 反射调用服务类中方法
			jinectmethod.invoke(aspectBeans.get(aspectClass),
					args == null ? new Object[1] : args);

		}
	}
}

StudentDao:


package com.tgb.dao;


/**
 * studendao,打印方法
* @ClassName: StudentDao 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author [qmx] 
* @date 
*
 */
public interface StudentDao {

	public void syaName();
}

TeacherDao:


package com.tgb.dao;

import com.tgb.domain.User;
/*
 * TeacherDao对象,增加删除,保存方法
 */

public interface TeacherDao {

	void save(User user);
	
	void update(User user);
	
	public void delete( User user);

}

UserDao:


package com.tgb.dao;

import com.tgb.domain.User;
/*
 * userdao对象,增加删除,保存方法
 */
public interface UserDao {

	void save(User user);
	
	void update(User user);
	
	public void delete( User user);
	
}

StudentDaoImpl:


package com.tgb.daoImpl;

import com.tgb.dao.StudentDao;
/*
 * StudentDaoImpl对象,打印方法
 */
public class StudentDaoImpl implements StudentDao {

	@Override
	public void syaName() {
		System.out.println("----my name is hanyk--");
		
	}

}

TeacherDaoImpl:


package com.tgb.daoImpl;

import com.tgb.dao.TeacherDao;
import com.tgb.dao.UserDao;
import com.tgb.domain.User;
/*
 * TeacherDaoImpl对象,增加删除,保存方法
 */
public class TeacherDaoImpl implements TeacherDao {

	@Override
	public void save(User user) {
	System.out.println( "这是业务类 "+this.getClass()+"-----的 save()方法-----");
		
	}
	
	@Override
	public void update(User user) {
		System.out.println( "这是业务类 "+this.getClass()+"-----的 update()方法-----");
		
	}

	@Override
	public void delete(User user) {
		System.out.println( "这是业务类 "+this.getClass()+"-----的 delete()方法-----");
		
	}

}

UserDaoImpl:


package com.tgb.daoImpl;

import com.tgb.dao.UserDao;
import com.tgb.domain.User;
/*
 * userdao对象,增加删除,保存方法
 */
public class UserDaoImpl implements UserDao {

	@Override
	public void save(User user) {
	System.out.println( "这是业务类 "+this.getClass()+"-----的 userDao.save()方法-----");
		
	}


	@Override
	public void update(User user) {
		System.out.println( "这是业务类 "+this.getClass()+"-----的 userDao.update()方法-----");
		
	}

	@Override
	public void delete(User user) {
		System.out.println( "这是业务类 "+this.getClass()+"-----的 userDao.delete()方法-----");
		
	}

}

User:


package com.tgb.domain;

public class User {

	private String userName;
	private String password;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

aspectbeans.xml:


<!--该文件 对是服务类的配置,所有服务类都需要在该文件进行注册-->
<beans>
	<!--服务类配置容器,配置缓存服务类,全名称 -->
	<aspectbean id="aspectCachBean" class="com.tgb.config.AspectCachBean"></aspectbean>


<!-- 	<aspectbean id="aspectCertifiyBean" class="com.tgb.configra.AspectCertifiyBean"></aspectbean> -->

</beans>

business.xml:


<!--该文件是业务类的配置-->
<beans>

	<!--用户bean注入-->
	<bean id="UserDao" class="com.tgb.daoImpl.UserDaoImpl" />
	<!--教师bean注入-->
	<bean id="TeacherDao" class="com.tgb.daoImpl.TeacherDaoImpl" />
	
</beans>

relationbean.xml:


<!--aop关系配置文件-->
<beans>	
	<!-- 是否启用aop -->
	<aop isaop="true"></aop>
	
<!-- 配置业务颗粒和服务类的增强关系method为业务类匹配的方法,可用正则表达式进行(未实现) ,aspectMethod为服务类拦截方法 -->
	<aspectbefore  aspectId="aspectCachBean" method="update"  aspectMethod="cacheSave"  ></aspectbefore>
	
</beans>









以上是关于Spring AOP 最终版实现的主要内容,如果未能解决你的问题,请参考以下文章

手写实现自定义简易版Spring (实现IoC 和 AOP)

如何实现一个简易版的 Spring

spring aop中this和target区别

从头认识Spring-3.5 简单的AOP日志实现(注解版)-某方法之前的前后记录日志

从头认识Spring-3.7 简单的AOP日志实现(注解版)-增加检查订单功能

Java之Spring AOP入门到精通IDEA版(一篇文章精通系列)