引言
Spring AOP 是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统1保护的1种技术。AOP是OOP的延续,是软件开发中的1个热门,也是Spring框架中的1个重要内容,是函数式编程的1种衍生范型。利用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("----启用aop1");
// 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(这里用1句话描写这个类的作用)
* @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(这里用1句话描写这个类的作用)
* @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>