-
基于 CGLib实现动态代理
JDK 动态代理需要被代理的类必须继承某一个接口
基于ASM的CGLib,可以为被代理的类动态生成子类,以解决 JDK动态代理对接口的束缚
-
实现 @Aspect、@Order 注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Aspect { // 表示当前被 Aspect 标记的横切逻辑,会织入到被属性逻辑标记的那些类中 Class extends Annotation> value(); } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Order { // 规定value越小优先级越高 int value(); } -
实现 DefaultAspect 所有切面必须继承 DefaultAspect
public abstract class DefaultAspect { public void before(Class> targetClass, Method method,Object[] args) throws Throwable{ } public Object afterReturning(Class> targetClass, Method method,Object[] args,Object returnValue)throws Throwable{ return returnValue; } public void afterThrowing(Class> targetClass, Method method,Object[] args,Throwable e) throws Throwable{ } } -
Aspect的排序以及Advice的定序执行
public class AspectInfo { private int orderIndex; private DefaultAspect aspectObject; }将 @Order 的值与 Aspect 的实现放入 List中,并将其按照 @Order 的值进行排序,以实现 Advice 的定序执行
-
横切逻辑的织入
通过 CGLib 实现横切逻辑的织入
@Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object returnValue = null; // 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方法 invokeAfterThrowingAdives(method, args, e); } return returnValue; }
Pointcut 粒度只能支持到注解级别,即只能筛选出被诸如 @Controller @Service 等注解标记的类的集合进行横切逻辑的织入
2.0 引入 AspectJ 的表达式解析功能
private PointcutExpression pointcutExpression;
public PointcutLocator(String expression) {
this.pointcutExpression = pointcutParser.parsePointcutExpression(expression);
}
public boolean roughMatches(Class> targetClass) {
// 只能校验within
// 不能校验(execution,call,get,set),面对无法校验的表达式,直接返回true
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
public boolean accurateMatches(Method method) {
ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
return shadowMatch.alwaysMatches();
}
相应的对1.0 进行修改
-
修改 @Aspect 注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Aspect { // 表示当前被 Aspect 标记的横切逻辑,被织入类的位置 String pointcut(); } -
修改对应的 AspectInfo
public class AspectInfo { // 优先级 private int orderIndex; // Aspect实例 private DefaultAspect aspectObject; // 依据 @Aspect 的值。为其注入对应的 PointcutExpression private PointcutLocator pointcutLocator; }
https://github.com/zunchang/simpleframework



