1. 本章须要实现的内容
- 实现AspectListExecutor类的编写
- 实现AspectWeaver类的编写
- 实现PointcutLocator类的编写
- 实现ProxyCreator类的编写
2. 实现PointcutLocator类的编写
2.1 须要实现的代码如下:
package com.wuyiccc.helloframework.aop;import org.aspectj.weaver.tools.PointcutExpression;import org.aspectj.weaver.tools.PointcutParser;import org.aspectj.weaver.tools.ShadowMatch;import java.lang.reflect.Method;/** * @author wuyiccc * @date 2020/7/14 9:03 * 岂曰无衣,与子同袍~ */public class PointcutLocator { /** * Pointcut解析器,间接给它赋值上Aspectj的所有表达式,以便反对对泛滥表达式的解析 */ private PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(PointcutParser.getAllSupportedPointcutPrimitives()); /** * 表达式解析器 */ private PointcutExpression pointcutExpression; public PointcutLocator(String expression) { this.pointcutExpression = pointcutParser.parsePointcutExpression(expression); } /** * 判断传入的Class对象是否是Aspect的指标代理类,即匹配Pointcut表达式(初筛) * * @param targetClass 指标类 * @return 是否匹配 */ public boolean roughMatches(Class<?> targetClass) { return pointcutExpression.couldMatchJoinPointsInType(targetClass); // 只能校验within,对于execution,call,get,set等无奈校验的表达式,间接返回true } /** * 判断传入的Method对象是否是Aspect的指标代理办法,即匹配Pointcut表达式(精筛) * @param method * @return */ public boolean accurateMatches(Method method) { ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method); if (shadowMatch.alwaysMatches()) { return true; } return false; }}
2.2 PointcutLocator类相干办法解说:
3. 实现AspectListExecutor类的编写
3.1 须要实现的代码如下:
package com.wuyiccc.helloframework.aop;import com.wuyiccc.helloframework.aop.aspect.AspectInfo;import com.wuyiccc.helloframework.util.ValidationUtil;import lombok.Getter;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import java.util.List;/** * @author wuyiccc * @date 2020/7/14 9:03 * 岂曰无衣,与子同袍~ */public class AspectListExecutor implements MethodInterceptor { private Class<?> targetClass; @Getter private List<AspectInfo> sortedAspectInfoList; public AspectListExecutor(Class<?> targetClass, List<AspectInfo> sortedAspectInfoList) { this.targetClass = targetClass; this.sortedAspectInfoList = sortAspectInfoList(sortedAspectInfoList); } /** * 依照order的值进行升序排序,确保Order值小的aspect先被织入 * * @param aspectInfoList * @return */ private List<AspectInfo> sortAspectInfoList(List<AspectInfo> aspectInfoList) { // 升序排列 Collections.sort(aspectInfoList, new Comparator<AspectInfo>() { @Override public int compare(AspectInfo o1, AspectInfo o2) { return o1.getOrderIndex() - o2.getOrderIndex(); } }); return aspectInfoList; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object returnValue = null; collectAccurateMatchedAspectList(method); if (ValidationUtil.isEmpty(sortedAspectInfoList)) { return methodProxy.invokeSuper(proxy, args); } // 1. 依照order的程序升序执行完所有Aspect的before办法 invokeBeforeAdvices(method, args); try { // 2. 执行被代理类的办法 returnValue = methodProxy.invokeSuper(proxy, args); // 3. 如果被代理办法失常返回,则依照order的程序降序执行完所有Aspect的afterReturning办法 invokeAfterReturningAdvices(method, args, returnValue); } catch (Exception e) { // 4. 如果被代理办法抛出异样,则依照order的程序降序执行完所有Aspect的afterThrowing办法 invokeAfterThrowingAdvices(method, args, e); } return returnValue; } private void collectAccurateMatchedAspectList(Method method) { if (ValidationUtil.isEmpty(sortedAspectInfoList)) { return; } Iterator<AspectInfo> it = sortedAspectInfoList.iterator(); while (it.hasNext()) { AspectInfo aspectInfo = it.next(); if (!aspectInfo.getPointcutLocator().accurateMatches(method)) { it.remove(); // 须要用Iterator自带的remove,不能用sortedAspectInfoList的remove,否则就会呈现并发批改异样 } } } private void invokeAfterThrowingAdvices(Method method, Object[] args, Exception e) throws Throwable { for (int i = sortedAspectInfoList.size() - 1; i >= 0; i--) { sortedAspectInfoList.get(i).getAspectObject().afterThrowing(targetClass, method, args, e); } } private void invokeAfterReturningAdvices(Method method, Object[] args, Object returnValue) throws Throwable { for (int i = sortedAspectInfoList.size() - 1; i >= 0; i--) { sortedAspectInfoList.get(i).getAspectObject().afterReturning(targetClass, method, args, returnValue); } } private void invokeBeforeAdvices(Method method, Object[] args) throws Throwable { for (AspectInfo aspectInfo : sortedAspectInfoList) { aspectInfo.getAspectObject().before(targetClass, method, args); } }}
3.2 AspectListExecutor类相干办法解说:
4. 实现ProxyCreator类的编写
4.1 须要实现的代码及解说如下:
5. 实现AspectWeaver类的编写
5.1 须要实现的代码如下:
package org.myframework.aop;import org.myframework.aop.annotation.Aspect;import org.myframework.aop.annotation.Order;import org.myframework.aop.aspect.AspectInfo;import org.myframework.aop.aspect.DefaultAspect;import org.myframework.core.BeanContainer;import org.myframework.util.ValidationUtil;import java.util.ArrayList;import java.util.List;import java.util.Set;/** * @author wuyiccc * @date 2020/6/16 8:49 * 岂曰无衣,与子同袍~ */public class AspectWeaver { private BeanContainer beanContainer; public AspectWeaver() { beanContainer = BeanContainer.getInstance(); } public void doAop() { // 1. 获取所有的切面类 Set<Class<?>> aspectSet = beanContainer.getClassesByAnnotation(Aspect.class); if (ValidationUtil.isEmpty(aspectSet)) { return; } // 2. 拼装AspectInfoList List<AspectInfo> aspectInfoList = packAspectInfoList(aspectSet); // 3. 遍历容器里的类 Set<Class<?>> classSet = beanContainer.getClasses(); for (Class<?> targetClass : classSet) { // 排除AspectClass本身 if (targetClass.isAnnotationPresent(Aspect.class)) { continue; } // 4. 粗筛符和条件的Aspect List<AspectInfo> roughMatchedAspectList = collectRoughMatchAspectListForSpecificClass(aspectInfoList, targetClass); // 5. 尝试进行Aspect织入 wrapIfNecessary(roughMatchedAspectList, targetClass); } } private void wrapIfNecessary(List<AspectInfo> roughMatchedAspectList, Class<?> targetClass) { if (ValidationUtil.isEmpty(roughMatchedAspectList)) { return; } // 创立动静代理对象 AspectListExecutor aspectListExecutor = new AspectListExecutor(targetClass, roughMatchedAspectList); Object proxyBean = ProxyCreator.createProxy(targetClass, aspectListExecutor); beanContainer.addBean(targetClass, proxyBean); } private List<AspectInfo> collectRoughMatchAspectListForSpecificClass(List<AspectInfo> aspectInfoList, Class<?> targetClass) { List<AspectInfo> roughMatchedAspectList = new ArrayList<>(); for (AspectInfo aspectInfo : aspectInfoList) { // 粗筛 if (aspectInfo.getPointcutLocator().roughMatches(targetClass)) { roughMatchedAspectList.add(aspectInfo); } } return roughMatchedAspectList; } private List<AspectInfo> packAspectInfoList(Set<Class<?>> aspectSet) { List<AspectInfo> aspectInfoList = new ArrayList<>(); for (Class<?> aspectClass : aspectSet) { if (verifyAspect(aspectClass)) { Order orderTag = aspectClass.getAnnotation(Order.class); Aspect aspectTag = aspectClass.getAnnotation(Aspect.class); DefaultAspect defaultAspect = (DefaultAspect) beanContainer.getBean(aspectClass); // 初始化表达式定位器 PointcutLocator pointcutLocator = new PointcutLocator(aspectTag.pointcut()); AspectInfo aspectInfo = new AspectInfo(orderTag.value(), defaultAspect, pointcutLocator); aspectInfoList.add(aspectInfo); } else { throw new RuntimeException("@Aspect and @Order must be added to the Aspect class, and Aspect class must extend from DefaultAspect"); } } return aspectInfoList; } // 框架中肯定要恪守给Aspect增加的@Aspect和@Order标签的标准,同时,必须继承自DefaultAspect.class private boolean verifyAspect(Class<?> aspectClass) { return aspectClass.isAnnotationPresent(Aspect.class) && aspectClass.isAnnotationPresent(Order.class) && DefaultAspect.class.isAssignableFrom(aspectClass); }}
5.2 AspectWeaver类相干办法解析:
github地址:https://github.com/wuyiccc/he...