Spring AOP基于配置文件的面向方法的切面

Spring AOP根据执行的时间点可以分为aroundbeforeafter几种方式。

  • around为方法前后均执行
  • before为方法前执行
  • after为方法后执行

这里只对around的方式进行介绍。本文只是摘录相应的思路,许多辅助类和方法不一一给出。因此下述方法并不能正常运行。

定义忽略权限检查注解类

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnorePermission {
}

定义需要权限检查的类及方法

@RestController
@RequestMapping(value = "/api/test")
public class TestController extends BaseController { @RequestMapping(value="", method= RequestMethod.POST)
public ResponseEntity postTest(@RequestParam(name = "accessToken") String accessToken) {
ResponseEntity responseEntity = new ResponseEntity(); return responseEntity;
} @RequestMapping(value = "/delete", method = RequestMethod.POST)
public ResponseEntity deleteTest(@RequestParam(name = "accessToken") String accessToken) {
ResponseEntity responseEntity = new ResponseEntity(); return responseEntity;
} /**
* 带了IgnorePermission注解,不进行权限检查。
*/
@IgnorePermission
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ResponseEntity getTestList(@RequestParam(name = "accessToken") String accessToken) { ResponseEntity responseEntity = new ResponseEntity(); return responseEntity;
}
}

定义切面aop类

public class PermissionAspect {

    private Logger logger = LoggerFactory.getLogger(PermissionAspect.class);

    private static final String DEFAULT_TOKEN_NAME = "accessToken";

    private TokenManager tokenManager;
private String tokenName; private boolean processing = true; @Autowired
private BasicService BasicService; public void setTokenManager(TokenManager tokenManager) {
this.tokenManager = tokenManager;
} public void setTokenName(String tokenName) {
if (StringUtils.isEmpty(tokenName)) {
tokenName = DEFAULT_TOKEN_NAME;
}
this.tokenName = tokenName;
} //ProceedingJoinPoint只有around的方式才可用
//JoinPoint则around、before和after均可用
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
processing = true;
ResponseEntity responseEntity = new ResponseEntity(); // 从切点上获取目标方法
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod(); // 若目标方法忽略权限检查,则直接调用目标方法
if (method.isAnnotationPresent(IgnorePermission.class)) {
return joinPoint.proceed();
} // 检查 该用户是否已经开通
// System.out.println("******************* PermissionAspect start ************************");
logger.info("******************* PermissionAspect start ************************"); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); // 从 request header 中获取当前 token
String token = StringUtils.isBlank(request.getHeader(tokenName)) ? request.getParameter("accessToken") : request.getHeader(tokenName); String userId = tokenManager.getUserId(token); TestBasic TestBasic = BasicService.findByUserId(userId); try { if (null == TestBasic) {
String message = String.format("Test basic userId [%s] is not exist.", userId);
responseEntity.failure(ResponseConstant.CODE_000, "尚未申请开通功能。");
processing = false;
throw new Exception(message);
} if (TestConstant.Test_BASIC_IS_PASS_PASSED != TestBasic.getIsPass()) {
String message = String.format("Test basic userId [%s] has no permission.", userId);
String tips = "不具备权限功能。";
if (TestConstant.Test_BASIC_IS_PASS_PROCESSING == TestBasic.getIsPass()) {
tips = "权限正在审核中。";
} else if (TestConstant.Test_BASIC_IS_PASS_DENY == TestBasic.getIsPass()) {
tips = "不具备权限。";
}
responseEntity.failure(ResponseConstant.CODE_000, tips);
processing = false;
throw new Exception(message);
}
} catch (Exception e) {
throw new Exception(e);
} finally {
// System.out.println("******************* PermissionAspect end ************************");
logger.info("******************* PermissionAspect end ************************");
if (processing) {
return joinPoint.proceed();//如果具备权限则执行相应的方法
} else {
return responseEntity;//如果不具备权限返回相应的json数据
}
}
}
}

配置文件的配置

开启切面支持

springMvc-context.xml中开启如下配置

<!-- 开启aspectj切面支持 -->
<aop:aspectj-autoproxy proxy-target-class="true" />

定义 bean

applicationContext.xml中添加如下配置

<!--Test权限检查-->
<bean id="permissionAspect" class="com.test.api.test.PermissionAspect">
<property name="tokenManager" ref="tokenManager" />
<property name="tokenName" value="accessToken" />
</bean>

AOP配置

applicationContext.xml中添加如下配置

<aop:config>

  <!--其他切面配置-->
... ... <!--问题权限切面检查-->
<aop:aspect ref="permissionAspect" order="2">
<aop:around method="execute" pointcut="execution( * com.test.api.test.controller.TestController.*(..) )"/>
</aop:aspect>
</aop:config>
  • 注:上述代码只是实现思路的摘录,代码不能直接运行。

Spring AOP基于配置文件的面向方法的切面的更多相关文章

  1. Spring Aop基于注解的实现

    一.AspectOriented Programing,面向切面编程.   AOP主要用于日志记录,性能统计,安全控制(权限控制),事务处理,异常处理等.将日志记录,性能统计,安全控制,事务处理,异常 ...

  2. Spring:基于配置文件的创建对象的各种方式

    在Spring3.0之前,Spring主要创建对象的方法是基于配置文件的,即在配置文件中为对象进行注册,并且可以在配置文件当中为对象的字段或者称之为属性值进行赋值,接下来首先介绍基于配置文件的创建对象 ...

  3. Spring AOP实现方式四之注入式AspectJ切面【附源码】

    现在我们要讲的是第四种AOP实现之注入式AspectJ切面 通过简单的配置就可以实现AOP了. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.ao ...

  4. spring aop在mvc的controller中加入切面无效

    spring aop在mvc的controller中加入切面无效 因为MVC的controller,aop默认使用jdk代理.要使用cglib代理. 在spring-mybatis.xml配置文件中加 ...

  5. [原创]java WEB学习笔记108:Spring学习---基于配置文件的形式实现AOP

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. spring-第十八篇之spring AOP基于XML配置文件的管理方式

    1.在XML配置文件中配置切面.切入点.增强处理.spring-1.5之前只能使用XML Schema方式配置切面.切入点.增强处理. spring配置文件中,所有的切面.切入点.增强处理都必须定义在 ...

  7. spring aop 基于schema的aop

    AOP的基本概念: 连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行.方法调用.字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP ...

  8. spring aop 动态代理批量调用方法实例

    今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候 ...

  9. spring-第十七篇之spring AOP基于注解的零配置方式

    1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...

随机推荐

  1. ASP.NET 生命周期

    学习资料:http://www.cnblogs.com/OceanEyes/archive/2012/08/13/2635657.html

  2. java批量生成excel代码分享

    package com.test.util; /** * @author ocq * */ import java.io.FileOutputStream; import java.io.IOExce ...

  3. [C#]如何使用ThreadPool

    摘要 线程池是一种多线程的形式,其中的任务被添加到队列中,并在创建线程时自动启动. 以下示例使用.Net框架的线程池来计算十个数字20和40之间的裴波那契的结果.裴波那契Fibonacci类,它提供了 ...

  4. mock.js-无需等待,让前端独立于后端进行开发

    概述 首先啦,我不认识mock.js的作者,带着需求找到mock.js让我觉得很惊艳. 相对于其他同类的框架的实现,mock.js超出了我的意料. 基于 数据模板 生成模拟数据. 基于 HTML模板 ...

  5. [设计模式] javascript 之 享元模式;

    享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的 ...

  6. R入门-第一次写了一个完整的时间序列分析代码

    纪念一下,在心心念念想从会计本科转为数据分析师快两年后,近期终于迈出了使用R的第一步,在参考他人的例子前提下,成功写了几行代码.用成本的角度来说,省去了部门去买昂贵的数据分析软件的金钱和时间,而对自己 ...

  7. [Storm] 内部消息缓存

    这篇文件翻译自 http://www.michael-noll.com/blog/2013/06/21/understanding-storm-internal-message-buffers/ 当进 ...

  8. nyoj 4 ASCII码排序 java

    java输入字符:1.String s=sc.next(); 2.char a=s.charAt(0); 注意:package   java 中提交不能带package java代码: import ...

  9. 使用原生JS封装Ajax

    使用原生 的JS封装 Ajax,实现 仿JQuery的Ajax,post,get三种异步请求方式: var MAjax = { //根据浏览器创建异步对象 createXhr: function () ...

  10. LoadRunner脚本编写(转)

    性能测试工程师要懂代码么?答案是必须的.好多测试员认为在loadrunner中编写脚本很难很牛X ,主要是大多测试人员并未做过开发工作,大学的那点程序基础也忘记的差不多了.还有非计算机专业出身的测试员 ...