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 sortedAspectInfoList;
public AspectListExecutor(Class> targetClass, List sortedAspectInfoList) {
this.targetClass = targetClass;
this.sortedAspectInfoList = sortAspectInfoList(sortedAspectInfoList);
}
/**
* 按照order的值进行升序排序,确保Order值小的aspect先被织入
*
* @param aspectInfoList
* @return
*/
private List sortAspectInfoList(List aspectInfoList) {
// 升序排列
Collections.sort(aspectInfoList, new Comparator() {
@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 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> aspectSet = beanContainer.getClassesByAnnotation(Aspect.class);
if (ValidationUtil.isEmpty(aspectSet)) {
return;
}
// 2. 拼装AspectInfoList
List aspectInfoList = packAspectInfoList(aspectSet);
// 3. 遍历容器里的类
Set> classSet = beanContainer.getClasses();
for (Class> targetClass : classSet) {
// 排除AspectClass自身
if (targetClass.isAnnotationPresent(Aspect.class)) {
continue;
}
// 4. 粗筛符和条件的Aspect
List roughMatchedAspectList = collectRoughMatchAspectListForSpecificClass(aspectInfoList, targetClass);
// 5. 尝试进行Aspect织入
wrapIfNecessary(roughMatchedAspectList, targetClass);
}
}
private void wrapIfNecessary(List 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 collectRoughMatchAspectListForSpecificClass(List aspectInfoList, Class> targetClass) {
List roughMatchedAspectList = new ArrayList<>();
for (AspectInfo aspectInfo : aspectInfoList) {
// 粗筛
if (aspectInfo.getPointcutLocator().roughMatches(targetClass)) {
roughMatchedAspectList.add(aspectInfo);
}
}
return roughMatchedAspectList;
}
private List packAspectInfoList(Set> aspectSet) {
List 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...