zoukankan      html  css  js  c++  java
  • 自定义注解实现(spring aop)

    1.基本概念

    1.1 aop

    即面向切面编程,优点是耦合性低,能使业务处理和切面处理分开开发,扩展和修改方面,当引入了注解方式时,使用起来更加方便。

    1.2 应用场景

    打日志、分析代码执行时间、权限控制、事务处理、访问频率控制、异常处理等等。

    1.3 主要概念

    几乎所有涉及aop的地方都会对这些概念进行说明,这里只说说个人的理解,可先了解一下基本概念,然后看完例子之后回头结合这些概念,才能更深刻的理解。

    Aspect:关注点的模块化。类似于类声明,包含PointCut和对应的Advice。在Spring AOP中被定义为接口@Aspect,作用于TYPE(类、接口、方法、enum)

    JoinPoint:程序执行过程中明确的点,如方法的调用或特定的异常被抛出。常用的是getArgs()用来获取参数,getTarget()获得目标对象。

    Pointcut:表示一组JoinPoint,这些JoinPoint或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。 在Spring AOP中被定义为作用于METHOD上的接口@Pointcut

    Introduction:添加方法或字段到被通知的类。

    Advice: 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个JoinPoint之前、之后还是代替执行的代码。

    Target Object:包含连接点的对象。也被称作被通知或被代理对象。POJO

    Weaving:组装方面来创建一个被通知对象。 

    2.原理浅析

    2.1 UML

    对于AOP的理解,首先需要看下UML图,大致有个概念。

    2.2 配置文件方式实现aop

    如果需要理解一样东西,首先要会用,再此基础上理解才会更加深刻。这里给出一个例子,例子原文http://www.cnblogs.com/hongwz/p/5764917.html

    这个例子相对比较容易理解一点,TimeHandler是Aspect,"execution(* com.bird.service.impl.PersonServiceBean.*(..))"是PointCut,before/after 是Advice,helloWordImpl1/helloWordImpl2是目标对象。

    3. 注解实现

    3.1 示例

    aop实现一般是针对现有代码基础上做一些其他操作,例如下面代码所示。

    这里一切以IOC为基础

    @Aspect修饰类,说明该类是切面关注的抽象,即针对切面目标对象要做什么操作。

    @Pointcut针对Spring MVC的RequestMapping和ResponseBody注解(@Iterface)。

    @Before、@After、@AfterReturing等针对目标对象相应动作(before、after等)做出相应的操作。

    JoinPoint joint 可以获取目标对象的参数。Object[] argcs= joinPoint.getArgs(); argcs类似于main方法的参数数组,只不过这里需要类型转换把Object转换成相应的type。

    3.2 实现

    这里以限制访问频率举例。在Controller上加上注解,设置参数就可以实现控制用户的某个时间段内的访问次数。用到Redis,如果没有Redis,可以用LocalThread代替。

    1. 自定义注解

      

    @Retention(RetentionPolicy.RUNTIME) :

    这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。此外RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略;RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略

    @Target

    定义注解的作用目标。@Target(ElementType.FIELD)表示该注解可以作用于类或者方法上

    @Order

    当有多个切面时,Order决定先执行哪个后执行哪个。如果不加Order则默认按照注解标注的先后顺序执行。@Order(Ordered.HIGHEST_PRECEDENCE)表示最高优先级。

     2.自定义切面

     如图所示@Aspect表示了该类是切面。

    @within:用于匹配所以持有指定注解类型内的方法;@annotation(limit) 是匹配含有limit注解的方法。

    @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)") 表示对含有SpringMVC的Controller注解下面的方法 且含有 注解limit的方法有效。

    jointPoint获取HttpServletRequest(被修饰的方法需要有HttpServletRequest参数)

    redis/Jedis不熟悉的只需要了解下两个方法就行:incr方法表示为key值加1,如果key不存在则新建一个key值,并初始化为1。expire表示经过time时间后key会消失。

    逻辑是某个Ip地址对某个接口url,在过期时间内如果超过规定的次数就会抛出访问频率过高的异常。

    3.在需要修饰的对象上加注解使用

    4.如果注解没有生效,检查下spring配置文件是否配置了aop

  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/sjlian/p/7325602.html
Copyright © 2011-2022 走看看