package cn.nosum.framework.aop.support; import cn.nosum.framework.aop.aspect.Advice; import cn.nosum.framework.aop.config.AopConfig; import cn.nosum.util.StringUtils; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; import java.util.regex.Matcher; public class AdvisedSupport { // 保存读取到的配置 private AopConfig config; private Object target; private Class targetClass; private Pattern pointCutClassPattern; private Map> methodCache; public AdvisedSupport(AopConfig config) { this.config = config; } // 解析配置文件的方法 private void parse() { // 把 Spring 的 Expression 变成Java能够识别的正则表达式 String pointCut = config.getPointCut() .replaceAll("\\.", "\\\\.") .replaceAll("\\\\.\\*", ".*") .replaceAll("\\(", "\\\\(") .replaceAll("\\)", "\\\\)"); // 保存专门匹配 Class 的正则 String pointCutForClassRegex = pointCut.substring(0, pointCut.lastIndexOf("\\(") - 4); pointCutClassPattern = Pattern.compile("class " + pointCutForClassRegex.substring(pointCutForClassRegex.lastIndexOf(" ") + 1)); if (pointCutMath()){ // 缓存 this.methodCache = new HashMap>(); // 保存专门匹配方法的正则 Pattern pointCutPattern = Pattern.compile(pointCut); try{ // 切面类,用户自己定义 Class aspectClass = Class.forName(this.config.getAspectClass()); Map aspectMethods = new HashMap(); // 取得切面类中的所有方法 for (Method method : aspectClass.getMethods()) { aspectMethods.put(method.getName(),method); } // 取得目标代理对象的所有方法 for (Method method : this.targetClass.getMethods()) { String methodString = method.toString(); // 截取方法名称 if(methodString.contains("throws")){ methodString = methodString.substring(0,methodString.lastIndexOf("throws")).trim(); } // 判断是否在切面的范围 Matcher matcher = pointCutPattern.matcher(methodString); if(matcher.matches()){ Map advices = new HashMap(); // 增加方法执行前的切面 if(StringUtils.isNotEmpty(config.getAspectBefore())){ advices.put("before",new Advice(aspectClass.newInstance(),aspectMethods.get(config.getAspectBefore()))); } // 增加方法执行后的切面 if(StringUtils.isNotEmpty(config.getAspectAfter())){ advices.put("after",new Advice(aspectClass.newInstance(),aspectMethods.get(config.getAspectAfter()))); } // 增加方法执行异常的切面 if(StringUtils.isNotEmpty(config.getAspectAfterThrow())){ Advice advice = new Advice(aspectClass.newInstance(),aspectMethods.get(config.getAspectAfterThrow())); // 设置要捕获的异常 advice.setThrowName(config.getAspectAfterThrowingName()); advices.put("afterThrow",advice); } // 跟目标代理类的业务方法和 Advices 建立一对多关联关系,以便在 Proxy 类中获得 this.methodCache.put(method,advices); } } }catch(Exception e){ e.printStackTrace(); } } } // 根据一个目标代理类的方法,获得其对应的通知 public Map getAdvices(Method method) throws NoSuchMethodException { //享元设计模式的应用 Map cache = methodCache.get(method); if(null == cache){ // 如果是通过父类的接口调用,无法根据key进行获取,此时,取得子类方法,并且调用 Method m = targetClass.getMethod(method.getName(),method.getParameterTypes()); cache = methodCache.get(m); // 缓存 this.methodCache.put(method,cache); } return cache; } // IOC 中的对象初始化时调用,决定要不要生成代理类的逻辑 public boolean pointCutMath() { return pointCutClassPattern.matcher(this.targetClass.toString()).matches(); } public void setTargetClass(Class targetClass) { this.targetClass = targetClass; parse(); } public void setTarget(Object target) { this.target = target; } public Class getTargetClass() { return targetClass; } public Object getTarget() { return target; } }