上篇咱们介绍了容器和AOP的结合,结合后如何将对象增强服务并没有过多的说明,这里将具体说明如何将对象 进行增强 ,达到一个一对多和多对多的增强方式
先从简单的方式说起
/** *JDK代理类,实现动态调用对象方法 */ public class JDKDynamicProxy implements InvocationHandler { /** *……省略方法 */ /** *回调用法,执行选择的方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result = method.invoke(target, args); after(); return result; } private void before() { System.out.println("Before"); } private void after() { System.out.println("After"); } }
以上代码转为图形为
我们将具体的颗粒固定在 了AOP中,这样一来,若再想增加服务颗粒可得改动代码,这不是一种很好的解决方式。为了更好更好的将服务与AOP解耦,我们将服务咱们装载到了一个服务容器中。这样就有了先前的版本
基本是我们需要的,通过截取业务颗粒,将服务颗粒,关系集合一起传递到AOP中,AOP进行解析。若是有多个服务颗粒呢,于是我们有了变更版本
将右侧的服务颗粒放在了一个容器中,多个服务颗粒同时为一个业务对象服务。若有多个服务颗粒,想要这写服务同时为所有业务颗粒提供支持,就成了如下图了
1 首先通过构造函数将所需要的参数传递进来
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; }
2 在回调函数中 调用解析关系xml方法,进行方法调用
// 回调注册切入对象方法 @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; } /** * * @Title: getAllMethod * @Description: 执行某个服务类中的所有方法, * @param @param clazz 服务类 * @param @param aspectClass aop关系集合中设定执行 拦截的方法 * @param @param args 被拦截对象的参数 * @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); } }
以上就是对AOP关系的基本解释,一步步逐渐演变,也不是一蹴而就的,所以回到学习上,也不是一次学习就可以完全的,要不断反复的思考和总结。具体的源码点击连接
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/han_yankun2009/article/details/46663713