架构探险-从零开始写Javaweb框架读书笔记(5)

    xiaoxiao2025-02-24  23

    AOP实现

    AOP(Aspect Oriented Programming,面向切面编程);用来不改变代码的情况下在方法前后加入性能监控,日志打印等等。

    首先请转到代理模式介绍

    依照惯例,有时spring aop的实现过程

    advice 直译为通知 黄勇老师说这是不可以的 要译为增强 so Before Advice 前置增强 After Advice 后置增强 Around Advice 环绕增强 Introduction Advice 引入增强

    源码分析

    //AspectJAfterAdvice.java //方法执行 public Object invoke(MethodInvocation mi) throws Throwable { Object var2; try { var2 = mi.proceed(); } finally { this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); } return var2; } //Joinpoint.java public interface Joinpoint { Object proceed() throws Throwable; Object getThis(); AccessibleObject getStaticPart(); } //ReflectiveMethodInvocation.java public Object proceed() throws Throwable { //如果当前的拦截器的下标等于此方法上面所有的拦截器的数量-1 ,那么当前的拦截器已经是此方法的最后拦截器。so 执行当前方法 if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return this.invokeJoinpoint(); } else { Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice; return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed(); } else { return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); } } }

    执行代理

    如以下流程图

    Created with Raphaël 2.1.0 执行被代理方法 获取代理链 末尾代理 代理匹配 执行代理 执行方法,返回结果 结束 yes no yes no

    我们可以按照这个流程图做我们的Aop代理

    /** * 方法拦截助手类 * * @author xueaohui */ public final class AopHelper { private static final Logger LOGGER = LoggerFactory.getLogger(AopHelper.class); static { try { //获取所有继承AspectProxy的类与代理的目标类映射 Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap(); //获取所有目标类 与 代理此目标 的代理类集合 映射 Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap); //遍历 for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) { Class<?> targetClass = targetEntry.getKey(); List<Proxy> proxyList = targetEntry.getValue(); //创建代理 Object proxy = ProxyManager.createProxy(targetClass, proxyList); //遍历添加代理为bean,如果已经被添加至bean类中 将会覆盖已存在的bean 现在的是一个有CGLib生成的代理类 BeanHelper.setBean(targetClass, proxy); } } catch (Exception e) { LOGGER.error("aop failure", e); } } private static Map<Class<?>, Set<Class<?>>> createProxyMap() throws Exception { Map<Class<?>, Set<Class<?>>> proxyMap = new HashMap<Class<?>, Set<Class<?>>>(); addAspectProxy(proxyMap); /** * 1. 为所有Service方法添加事务代理 * 2. 判断是否有事务注解 * 3. 有事务注解的开启事务->执行方法->提交事务 * 4. 无事务注解的执行方法(应用于单条查询) */ addTransactionProxy(proxyMap); return proxyMap; } private static void addTransactionProxy(Map<Class<?>,Set<Class<?>>> proxyMap){ Set<Class<?>> serviceClassSet = ClassHelper.getServiceClassSet(); proxyMap.put(TransactionProxy.class,serviceClassSet); } private static void addAspectProxy(Map<Class<?>, Set<Class<?>>> proxyMap) throws Exception { //获取实现切面代理的类 Set<Class<?>> proxyClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class); for (Class<?> proxyClass : proxyClassSet) { //如果有@Aspect注解 加入代理类的 if (proxyClass.isAnnotationPresent(Aspect.class)) { Aspect aspect = proxyClass.getAnnotation(Aspect.class); Set<Class<?>> targetClassSet = createTargetClassSet(aspect); proxyMap.put(proxyClass, targetClassSet); } } } 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)) { //获取有 切面注解value中的注解 的类 ,加入此注解的目标类中 targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation)); } return targetClassSet; } /** * 获取 目标类的代理类列表 映射 */ private static Map<Class<?>, List<Proxy>> createTargetMap(Map<Class<?>, Set<Class<?>>> proxyMap) throws Exception { Map<Class<?>, List<Proxy>> targetMap = new HashMap<Class<?>, List<Proxy>>(); 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<Proxy>(); proxyList.add(proxy); targetMap.put(targetClass, proxyList); } } } return targetMap; } }
    转载请注明原文地址: https://ju.6miu.com/read-1296610.html
    最新回复(0)