AOP框架实现

本文参照《架构探险》一书。html

aop 无非是在原有的方法先后加入自定义的代码。整体思想:java

  1. 经过cglib或jvm动态代理技术生成对目标方法的代理类
  2. 将容器中的原实例替换为新生成的代理类实例

JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。 由于是继承,因此该类或方法最好不要声明成final ,final能够阻止继承和多态。架构

<aop:aspectj-autoproxy proxy-target-class="true"/> 强制使用cglib作动态代理框架

AOP框架

public class AopHelper {
...
    static {
        try {
            //从容器中找到代理类和被代理类的关系
            Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap();
            Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap);

            for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) {
                //1.建立代理类
                Object proxy = ProxyManager.createProxy(targetEntry.getKey(), targetEntry.getValue());
                //2.将容器中的class 换为 代理类
                BeanHelper.setBean(targetEntry.getKey(), proxy);

            }
        } catch (Exception e) {
            LOGGER.error("aop fail",e);
        }

    }	
  ...
}

切面类

@Aspect(Controller.class)
public class ControllerAspect extends AspectProxy

extends AspectProxy 实现父类方法,也就是咱们要添加的操做。jvm

@Aspect(Controller.class) 表示这个代理类代理的是哪一个类(具体方法代理规则能够在代理类方法中判断,作不一样处理)ide

从容器中找到代理类和被代理类的关系

/**
    * class集合中找到指定切面的集合
    * @param aspect
    * @return
    * @throws Exception
    */
   private static Set<Class<?>> createTargetClassSet(Aspect aspect) throws Exception {
       Set<Class<?>> targetClassSet = new HashSet<Class<?>>();
       Class<? extends Annotation> annotation = aspect.value();
       if (annotation != null && !annotation.equals(Aspect.class)) {
           targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation));
       }
       return targetClassSet;
   }

   /**
    * 找到继承AspectProxy的代理类
    * 根据代理类的Aspect注解中value 找到被代理类
    * 返回代理类和被代理类的映射
    * proxyClass -> set<targetClass>
    * @return
    * @throws Exception
    */
   private static Map<Class<?>, Set<Class<?>>> createProxyMap() throws Exception {
       Map<Class<?>, Set<Class<?>>> proxyMap = new HashMap<>();

       //切面类
       Set<Class<?>> proxyClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class);
       for (Class<?> proxyCls : proxyClassSet) {
           if (proxyCls.isAnnotationPresent(Aspect.class)){//继承了AspectProxy而且被Aspect标注
               Aspect aspect = proxyCls.getAnnotation(Aspect.class);
               Set<Class<?>> targetClassSet = createTargetClassSet(aspect);
               proxyMap.put(proxyCls, targetClassSet);
           }
       }

       //添加事务代理
       addTransactionProxy(proxyMap);

       return proxyMap;
   }

   private static void addTransactionProxy(Map<Class<?>, Set<Class<?>>> proxyMap) {
       Set<Class<?>> serviceClassSet = ClassHelper.getClassSetByAnnotation(Service.class);
       proxyMap.put(TransactionProxy.class, serviceClassSet);
   }

   /**
    * targetClass -> List<proxy instance>
    * @param proxyMap
    * @return
    * @throws Exception
    */
   private static Map<Class<?>, List<Proxy>> createTargetMap(Map<Class<?>, Set<Class<?>>> proxyMap) throws Exception {
       HashMap<Class<?>, List<Proxy>> targetMap = new HashMap<>();
       for (Map.Entry<Class<?>, Set<Class<?>>> proxyEntry : proxyMap.entrySet()) {
           Class<?> proxyClass = proxyEntry.getKey();
           Set<Class<?>> targetClassSet = proxyEntry.getValue();
           for (Class<?> targetClass : targetClassSet) {
               Proxy proxy = (Proxy) proxyClass.newInstance();
               if (targetMap.containsKey(targetClass)) {
                   targetMap.get(targetClass).add(proxy);
               } else {
                   List<Proxy> proxyList = new ArrayList<>();
                   proxyList.add(proxy);
                   targetMap.put(targetClass, proxyList);
               }
           }
       }
       return targetMap;
   }

如何建立代理对象

//cglib 建立代理对象
public class ProxyManager {
    public static <T> T createProxy(final Class<T> targetClass, final List<Proxy> proxyList) {
        //CGLib提供建立代理对象,代理对象是一个代理链
        return (T) Enhancer.create(targetClass, new MethodInterceptor() {
            @Override
            public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {
                //返回代理对象 代理链 的结果
                return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();
            }
        });
    }
}

代理对象是ProxyChain类型,由于同一个class可能有多个aop须要处理,因此是一条链。this

Enhancer.create

ProxyChain的执行

public class ProxyChain {

    private final Class<?> targetClass;
    private final Object targetObject;
    private final Method targetMethod;
    private final MethodProxy methodProxy;
    private final Object[] methodParams;
    
  ...
    
    public Object doProxyChain() throws Throwable {
        Object methodResult;
        if (proxyIndex < proxyList.size()) {
            methodResult = proxyList.get(proxyIndex++).doProxy(this);
        } else {
            //最后执行目标对象的业务逻辑
            //方法代理,参数只传入哪一个对象,什么参数
            methodResult = methodProxy.invokeSuper(targetObject, methodParams);
        }
        return methodResult;
    }
}

代理对象

切面代理

public abstract class AspectProxy implements Proxy{
    private static final Logger LOGGER = LoggerFactory.getLogger(AspectProxy.class);

    @Override
    public Object doProxy(ProxyChain proxyChain) throws Throwable {
        Object result = null;
        Class<?> targetClass = proxyChain.getTargetClass();
        Object[] methodParams = proxyChain.getMethodParams();
        Method targetMethod = proxyChain.getTargetMethod();

        begin();

        try {
            if (intercept(targetClass, targetMethod, methodParams)) {
                before(targetClass, targetMethod, methodParams);
                result = proxyChain.doProxyChain();
                after(targetClass, targetMethod, methodParams, result);
            } else {
                result = proxyChain.doProxyChain();
            }
        } catch (Exception e) {
            LOGGER.error("proxy fail",e);
            error(targetClass, targetMethod, methodParams, e);
            throw e;
        } finally {
            end();
        }
        return result;
    }

    private void begin() {
    }

    public boolean intercept(Class<?> cls, Method method, Object[] params) {
        return true;
    }

    public void before(Class<?> cls, Method method, Object[] params) {

    }

    public void after(Class<?> cls, Method method, Object[] params, Object result) {

    }

    public void error(Class<?> cls, Method method, Object[] params, Throwable e) {

    }

    public void end() {}

}

事务代理

public class TransactionProxy implements Proxy {

    //保证同一线程中事务控制相关逻辑只会执行一次?
    private static final ThreadLocal<Boolean> FLAG_HOLDER = new ThreadLocal<Boolean>(){
        protected Boolean initialValue() {
            return false;
        }
    };

    @Override
    public Object doProxy(ProxyChain proxyChain) throws Exception, Throwable {
        Boolean flag = FLAG_HOLDER.get();
        Method method = proxyChain.getTargetMethod();
        Object result = null;
        if (!flag && method.isAnnotationPresent(Transaction.class)) {
            FLAG_HOLDER.set(true);
            try {
                DatabaseHelper.beginTransaction();
                LOGGER.debug("begin transaction");
                result = proxyChain.doProxyChain();
                DatabaseHelper.commitTransaction();
                LOGGER.debug("commit transaction");
            } catch (Exception e) {
                DatabaseHelper.rollbackTransaction();
                LOGGER.debug("rollback transaction");
                throw e;
            } finally {
                //DatabaseHelper.closeConnetion();
                FLAG_HOLDER.remove();
            }
        } else {
            result = proxyChain.doProxyChain();
        }
        return result;
    }
}

FLAG_HOLDER应该是防止事务的嵌套,好比两个service都标注了@transaction,一个serviceA一个ServiceB, 可是ServiceA中又调用了ServiceB,这样没有FLAG_HOLDER就会先启动A的事务,再启动B的事务(A的事务还没完)。加上FLAG_HOLDER就只会启动A的事务,B看到已经有事务在执行就不启动事务,默认加入了A的事务。.net

相关文章
相关标签/搜索