Spring AOP面向切面编程:理解篇

1、使用@interface关键定义注解(RateLimiter.java),如下:

package com.vx.servicehi.annotation;

import java.lang.annotation.*;

/**
 * @author wangbs
 * @version 1.0
 * @date 2019/12/16 1:25
 * @className RateLimiter
 * @desc 限流注解
 */

//注解作用域
//        ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
//        ElementType.FIELD:允许作用在属性字段上
//        ElementType.METHOD:允许作用在方法上
//        ElementType.PARAMETER:允许作用在方法参数上
//        ElementType.CONSTRUCTOR:允许作用在构造器上
//        ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
//        ElementType.ANNOTATION_TYPE:允许作用在注解上
//        ElementType.PACKAGE:允许作用在包上
//
//        注解的生命周期
//        RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
//    RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
//    RetentionPolicy.RUNTIME:永久保存,可以反射获取

// 注解的作用域
@Target(ElementType.METHOD)
// 注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
// 允许子类继承
@Inherited
// 生成javadoc的时候生成注解的信息
@Documented
public @interface RateLimiter {

    /**
     * 限流key
     * @return
     */
    String key() default "rate:limiter";
    /**
     * 单位时间限制通过请求数
     * @return
     */
    long limit() default 10;

    /**
     * 过期时间,单位秒
     * @return
     */
    long expire() default 1;

    /**
     * 限流提示语
     * @return
     */
    String message() default "false";
}

2、在普通类上使用注解,使用方法

 
 
package com.vx.servicehi.controller;

import com.vx.servicehi.annotation.RateLimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("business")
public class BusinessController {
private static final Logger LOGGER = LoggerFactory.getLogger(BusinessController.class);

private static final String MESSAGE = "{\"code\":\"400\",\"msg\":\"FAIL\",\"desc\":\"触发限流\"}";


@Value("${server.port}")
String port;

/**
* 使用自定义注解 限流
* @param name
* @return
*/
@RequestMapping("/hi")
@RateLimiter(key = "business/hi", limit = 5, expire = 10, message = MESSAGE)
public String home(@RequestParam(value = "name", defaultValue = "forezp") String name) {
return "hi " + name + " ,i am from port:" + port;
}
}
 

3、解析注解,通过反射获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑

 
 
package com.vx.servicehi.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
* 解析注解
* 通过反射获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
*
* 对于一个类或者接口来说,Class 类中提供了以下一些方法用于反射注解。
getAnnotation:返回指定的注解
isAnnotationPresent:判定当前元素是否被指定注解修饰
getAnnotations:返回所有的注解
getDeclaredAnnotation:返回本元素的指定注解
getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的
*
* @author wangbs
* @date 2019-12-21 22:52:42
* 主要是对自定义注解 RateLimiter 的获取 测试
*
*/
public class ParseDecription {

public static void main(String[] args) {
// TODO Auto-generated method stub
// 1、使用类加载器加载类
try {
Class c = Class.forName("com.vx.servicehi.controller.BusinessController");
System.out.println(c);

// 2、找到类上面的注解
boolean isExist = c.isAnnotationPresent(RateLimiter.class);

if(isExist) {
// 3、拿到注解实例
RateLimiter d = (RateLimiter) c.getAnnotation(RateLimiter.class);
System.out.println("========parse class annotation=========");
System.out.println("desc = " + d.key());
System.out.println("author = " + d.message());
System.out.println("age = " + d.limit());
}

// 4、找到方法上的注解
Method[] ms = c.getMethods();
for (Method m : ms) {
boolean isMExist = m.isAnnotationPresent(RateLimiter.class);
if(isMExist) {
RateLimiter d = m.getAnnotation(RateLimiter.class);
System.out.println("========parse method annotation=========");
System.out.println("desc = " + d.key());
System.out.println("author = " + d.message());
System.out.println("age = " + d.limit());
}
}

// 另外一种解析方法
for (Method m : ms) {
Annotation[] annotations = m.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof RateLimiter) {
System.out.println("========parse method annotation other way=========");
RateLimiter d = (RateLimiter) annotation;
System.out.println("desc = " + d.key());
System.out.println("author = " + d.message());
System.out.println("age = " + d.limit());
}
}
}

} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

猜你喜欢

转载自www.cnblogs.com/xiaowangbangzhu/p/12071841.html
今日推荐