一、需解决的问题
-
部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法。
第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如:
boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!isValid) return ErrorUtil.buildError(ErrorUtil.ERR_CODE_COM_SING);
第二种实现方式(Spring Interception):利用spring的拦截器功能,对指定的接口进行拦截,拦截器实现签名校验算法,例如:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/connect/share/**" /> <mvc:mapping path="/friend/**" /> <mvc:mapping path="/account/get_bind" /> <mvc:mapping path="/account/get_associate" /> <bean class="com.sogou.upd.passport.web.inteceptor.IdentityAndSecureInteceptor" /> </mvc:interceptor> </mvc:interceptors>
第三种实现方式(spring AOP):自定义注解,对需要进行签名验证的方法添加注解,例如:
@SecureValid @ResponseBody @RequestMapping(value = "/share/add", method = RequestMethod.POST) public Object addShare(HttpServletRequest req, HttpServletResponse res,InfoAPIRequestParams requestParams) { ... }
2. 日志记录功能,例如:某些接口需要记录请求和响应,执行时间,类名,方法名等日志信息。也可采用以上三种方式实现。
3. 代码性能监控问题,例如方法调用时间、次数、线程和堆栈信息等。这类问题在后一个专题提出解决方案,采用以上三种方式实现缺点太多。
以下是三种实现方式比较:
实现方式 | 优点 | 缺点 |
Origin | 不采用反射机制,性能最佳 |
逻辑复杂时,代码复用不好 需要在每个接口里写入相同代码(我太懒,就想写几个字母) |
Spring Inter | 非常适合对所有方法进行拦截,例如调试时打印所有方法执行时间 类似过滤器的功能,如日志处理、编码转换、权限检查 是AOP的子功能 |
不采用反射机制,性能有所影响 需要在xml文件里配置对哪些接口进行拦截,比较麻烦 |
Spring AOP | 使用方便,增加一个注解 非常灵活,可@Before,@After,@Around等 |
不采用反射机制,性能有所影响(性能对比后面详细展示) |
二、Spring AOP 自定义注解的实现
在Maven中加入以下以依赖:
<!-- Spring AOP + AspectJ by shipengzhi --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>3.0.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>3.0.6.RELEASE</version> </