package org.theonefx.wcframework.aop; import java.lang.reflect.Method; import org.theonefx.wcframework.aop.exception.AopMetadataException; import org.theonefx.wcframework.utils.StringUtils; import org.theonefx.wcframework.utils.WildcardMatcher; /** * @File : ExpressionPointcut.java * @ClassName : ExpressionPointcut * @Author : TheoneFx * @Date : 2013-3-7 下午01:40:16 * @Version : v1.0 * @Description : 基于表达式的切入点<br> * 表达式规则:<br> * [a]:[b]([c])<br> * [a]代表class部分。 必填 可以使用包名.类名的方式,也可以使用通配符。<br> * [b]代表mathod部分。 必填 可以使用方法全名,也可以部分输入然后使用通配符。<br> * [c]代表args部分。 可不填 如果填写,外层必须使用圆括号,如果内部有多个参数,各个参数之间使用逗号','分隔,参数如果是基本类型可以使用基本类型的小写形式代替,如果是自定义类型,那么需要填写类全名和包名,同样支持通配符;<br> * 如果不填写,圆括号也可以省略;当然也可以只写一个圆括号内部不填写内容。<br> * [a][b]之间使用:分隔<br> * [a][b][c]三个部分都可以使用如下通配符<br> * * 代表任意长度字符串<br> * ? 代表任意一个字符<br> */ public class ExpressionPointcut implements Pointcut { private final String expression; private String classPart; private String methodPart; private String[] argsPart; public ExpressionPointcut(String expression) { if (StringUtils.isBlank(expression)) { error("表达式为空"); } this.expression = StringUtils.trimWhitespace(expression); parseExpression(); } private void parseExpression() { int index1 = expression.indexOf(":"); int index2 = expression.indexOf("("); int index3 = expression.lastIndexOf(")"); if (index1 < 0) { error("表达式没有类和方法的分隔符':'"); } if (index1 == 0) { error("没有定义类和包部分"); } if (index2 >= 0) { if (index2 == index1 + 1) { error("表达式没有定义方法部分"); } if (index3 < index2) { error("参数表达式没有闭合"); } } else { if (index1 + 1 == expression.length()) { error("表达式没有定义方法部分"); } } classPart = expression.substring(0, index1); String argsExpression; if (index2 > 0) { methodPart = expression.substring(index1 + 1, index2); argsExpression = expression.substring(index2 + 1, index3); if(StringUtils.isBlank(argsExpression)){ argsExpression = "*"; } } else { methodPart = expression.substring(index1 + 1); argsExpression = "*"; } if (!"*".equals(argsExpression)) { argsPart = argsExpression.split(","); } } @Override public ClassFilter getClassFilter() { return expressClassFilter; } @Override public MethodMatcher getMethodMatcher() { return expressMethodMatcher; } private ClassFilter expressClassFilter = new ClassFilter() { @Override public boolean matches(Class<?> clazz) { String fullname = clazz.getCanonicalName(); return WildcardMatcher.match(fullname, classPart); } }; private MethodMatcher expressMethodMatcher = new MethodMatcher() { @Override public boolean match(Method method) { // 不匹配Object原生的方法,这些方法AOP了也没有意义 if (method.getDeclaringClass() == Object.class) { return false; } String methodName = method.getName(); boolean match = WildcardMatcher.match(methodName, methodPart); if (match) { if (argsPart != null) { Class<?>[] types = method.getParameterTypes(); if (types.length != argsPart.length) { match = false; } else { for (int i = 0; i < types.length; i++) { match = match && WildcardMatcher.match(types[i].getCanonicalName(), argsPart[i]); if (!match) { break; } } } } } return match; } }; private void error(String reason) { throw new AopMetadataException("无效的表达式'" + expression + "':" + reason); } public static void main(String[] args) { } }