1. 实现自研框架AOP1.0
- 使用CGLIB来实现:不需要业务类实现接口,相对灵活
- 解决标记的问题,定义横切逻辑的框架
- 定义Aspect横切逻辑以及被代理方法的执行顺序
- 将横切逻辑织入到被代理的对象以生成动态代理对象
2. 解决横切逻辑的标记问题以及定义Aspect骨架
- 定义与横切逻辑相关的注解
- 定义供外部使用的横切逻辑骨架
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Aspect { // 需要被织入横切逻辑的注解标签 Class<? extends Annotation> value(); } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Order { // 控制类的执行顺序,值越小优先级越高 int value(); } public abstract class DefaultAspect { /** * 事前拦截 * @param targetClass 被代理的目标类 * @param method 被代理的目标方法 * @param args 被代理的目标方法对应的参数列表 * @throws Throwable * 模板方法中的钩子方法 */ public void before(Class<?> targetClass, Method method, Object[] args) throws Throwable { } /** * 事后拦截 * @param targetClass 被代理的目标类 * @param method 被代理的目标方法 * @param args 被代理的目标方法对应的参数列表 * @param returnValue 被代理的目标方法执行后的返回值 * @return * @throws Throwable */ public Object afterReturning(Class<?> targetClass, Method method, Object[] args, Object returnValue) throws Throwable { return returnValue; } /** * 事后拦截 * @param targetClass 被代理的目标类 * @param method 被代理的目标方法 * @param args 被代理的目标方法对应的参数列表 * @param e 被代理的目标方法抛出的异常 * @throws Throwable */ public void afterThrowing(Class<?> targetClass, Method method, Object[] args, Throwable e) throws Throwable { } }
3. 实现Aspect横切逻辑以及被代理方法的定序执行
- 创建MethodInterceptor的实现类
- 定义必要的成员变量 -- 被代理的类以及Aspect列表
- 按照Order对Aspect进行排序
- 实现对横切逻辑以及被代理对象方法的定序执行
@AllArgsConstructor @Getter public class AspectInfo { private int orderIndex; private DefaultAspect aspectObject; } public class AspectListExecutor implements MethodInterceptor { // 被代理的类 private Class<?> targetClass; // 排好序的Aspect列表 @Getter private List<AspectInfo> sortedAspectInfoList; public AspectListExecutor(Class<?> targetClass, List<AspectInfo> aspectInfoList) { this.targetClass = targetClass; this.sortedAspectInfoList = sortAspectInfoList(aspectInfoList); } /** * 按照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; if(ValidationUtil.isEmpty(sortedAspectInfoList)) { return returnValue; } // 1. 按照order的顺序升序执行完所有Aspect的before方法 invokeBeforeAdvices(method, args); try { // 2. 执行被代理类的方法 returnValue = methodProxy.invokeSuper(proxy, args); // 3. 如果被代理方法正常返回,则按照order的顺序降序执行完所有Aspect的afterReturning方法 returnValue = invokeAfterReturningAdvices(method, args, returnValue); } catch (Exception e) { // 4. 如果被代理方法抛出异常,则按照order的顺序降序执行完所有Aspect的afterThrowing方法 invokeAfterThrowingAdvices(method, args, e); } return returnValue; } // 4. 如果被代理方法抛出异常,则按照order的顺序降序执行完所有Aspect的afterThrowing方法 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); } } // 3. 如果被代理方法正常返回,则按照order的顺序降序执行完所有Aspect的afterReturning方法 private Object invokeAfterReturningAdvices(Method method, Object[] args, Object returnValue) throws Throwable { Object result = null; for(int i = sortedAspectInfoList.size() - 1; i >= 0; i--) { result = sortedAspectInfoList.get(i).getAspectObject().afterReturning(targetClass, method, args, returnValue); } return result; } // 1. 按照order的顺序升序执行完所有Aspect的before方法 private void invokeBeforeAdvices(Method method, Object[] args) throws Throwable { for(AspectInfo aspectInfo : sortedAspectInfoList) { aspectInfo.getAspectObject().before(targetClass, method, args); } } } public class ProxyCreator { /** * 创建动态代理对象并返回 * @param targetClass 被代理的Class对象 * @param methodInterceptor 方法拦截器 * @return */ public static Object createProxy(Class<?> targetClass, MethodInterceptor methodInterceptor) { return Enhancer.create(targetClass, methodInterceptor); } }
4. 将横切逻辑织入到被代理的对象以生成动态代理对象
public class AspectWeaver { private BeanContainer beanContainer; public AspectWeaver() { this.beanContainer = BeanContainer.getInstance(); } public void doAop() { // 1. 获取所有的切面类 Set<Class<?>> aspectSet = beanContainer.getClassesByAnnotation(Aspect.class); // 2. 将切面类按照不同的织入目标进行切分 Map<Class<? extends Annotation>, List<AspectInfo>> categorizedMap = new HashMap<>(); if(ValidationUtil.isEmpty(aspectSet)) { return; } for(Class<?> aspectClass : aspectSet) { if(verifyAspect(aspectClass)) { categorizeAspect(categorizedMap, aspectClass); } else { throw new RuntimeException("@Aspect and @Order have not been added to the Aspect class, " + "or Aspect class does not extend from DefaultAspect, or the value in Aspect Tag equals @Aspect"); } } // 3. 按照不同的织入目标分别去按序织入Aspect的逻辑 if(ValidationUtil.isEmpty(categorizedMap)) { return; } for(Class<? extends Annotation> category : categorizedMap.keySet()) { weaveByCategory(category, categorizedMap.get(category)); } } private void weaveByCategory(Class<? extends Annotation> category, List<AspectInfo> aspectInfoList) { // 1. 获取被代理类的集合 Set<Class<?>> classSet = beanContainer.getClassesByAnnotation(category); if(ValidationUtil.isEmpty(classSet)) { return; } // 2. 遍历被代理类,分别为每个被代理类生成动态代理实例 for(Class<?> targetClass : classSet) { // 创建动态代理对象 AspectListExecutor aspectListExecutor = new AspectListExecutor(targetClass, aspectInfoList); Object proxyBean = ProxyCreator.createProxy(targetClass, aspectListExecutor); // 3. 将动态代理对象实例添加到容器里,取代未被代理的类实例 beanContainer.addBean(targetClass, proxyBean); } } // 2. 将切面类按照不同的织入目标进行切分 private void categorizeAspect(Map<Class<? extends Annotation>, List<AspectInfo>> categorizedMap, Class<?> aspectClass) { Order orderTag = aspectClass.getAnnotation(Order.class); Aspect aspectTag = aspectClass.getAnnotation(Aspect.class); DefaultAspect aspect = (DefaultAspect) beanContainer.getBean(aspectClass); AspectInfo aspectInfo = new AspectInfo(orderTag.value(), aspect); if(!categorizedMap.containsKey(aspectTag.value())) { // 如果织入的joinpoint第一次出现,则以该joinpoint为key,以创建新的List<AspectInfo>为value List<AspectInfo> aspectInfoList = new ArrayList<>(); aspectInfoList.add(aspectInfo); categorizedMap.put(aspectTag.value(), aspectInfoList); } else { // 如果织入的joinpoint不说话第一次出现,则往joinpoint对应的value里添加新的Aspect逻辑 List<AspectInfo> aspectInfoList = categorizedMap.get(aspectTag.value()); aspectInfoList.add(aspectInfo); } } // 框架中一定要遵守给Aspect类添加@Aspect和@Order标签的规范,同时,必须继承自DefaultAspect.class // 此外,@Aspect的属性值不能是它本身 private boolean verifyAspect(Class<?> aspectClass) { return aspectClass.isAnnotationPresent(Aspect.class) && aspectClass.isAnnotationPresent(Order.class) && DefaultAspect.class.isAssignableFrom(aspectClass) && aspectClass.getAnnotation(Aspect.class).value() != Aspect.class; } }