Spring 创建一个自定义注解

您所在的位置:网站首页 competent注解 Spring 创建一个自定义注解

Spring 创建一个自定义注解

#Spring 创建一个自定义注解| 来源: 网络整理| 查看: 265

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

前言

平时在用springBoot的使用,常常会用到@Service,@Compent等等注解,简化了我们的开发流程,提升了开发效率.那如何自己来写一个注解呢?下面就来介绍一下。

写一个注解

创建一个注解主要分两部分,一部分是创建注解类,一部分是创建一个切面类。

创建注解类 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnn { String value() default "d"; } 复制代码

创建注解类的关键字就是@interface,这个注解类设置了一个value变量,默认值为d;

在注解类上面还有@Target和@Retention注解,下面来说说创建注解类时需要用到的几个注解:

@Target

用来标记这个注解可以用于哪些地方,与ElementType枚举类搭配使用,那这个枚举类里面有什么内容呢?

public enum ElementType { /** 类,接口(包括注释类型)或枚举声明*/ TYPE, /** 字段声明(包括枚举常量)*/ FIELD, /** 方法声明*/ METHOD, /** 形式参数(形参-调用方法时传入的参数)声明 */ PARAMETER, /** 构造函数声明 */ CONSTRUCTOR, /** 局部变量声明 */ LOCAL_VARIABLE, /** 注释类型声明 */ ANNOTATION_TYPE, /** 包声明 */ PACKAGE, /** * 类型参数声明 * java8新特性: * @since 1.8 */ TYPE_PARAMETER, /** * 任何类型声明 * java8新特性: * @since 1.8 */ TYPE_USE } 复制代码 @Retention

该注解表示自定义注解的生命周期

public enum RetentionPolicy { /** * 注释将被编译器丢弃。 */ SOURCE, /** * 注释由编译器记录在类文件中 * 但不必在运行时由VM保留。 这是默认值 */ CLASS, /** *注释由编译器记录在类文件中,并且 *在运行时由VM保留,因此可以以反射方式读取它们。 */ RUNTIME } 复制代码 写一个切面类

因为用到了切面,所以我们要先导入Spring AOP这个依赖包。

org.springframework.boot spring-boot-starter-aop 复制代码 创建切面类 @Aspect @Component public class MyAnnAop { private Logger logger= LoggerFactory.getLogger(MyAnnAop.class); @Pointcut("@annotation(com.example.demo.annotation.MyAnn)") public void ann(){ } @Before("ann()") public void before(JoinPoint joinPoint){ logger.info("打印:开始前"); } @AfterReturning(value = "ann()",returning = "res") public Object dochange(JoinPoint joinPoint,Object res){ logger.info("AfterReturning通知开始-获取数据:{}",res); //获取数据 Map map= (Map) res; //添加新值 map.put("s1","我是在AOP中添加的新值"); return map; } } 复制代码 Spring AOP说明

具体可以查阅Spring AOP相关资料

注解说明@Before前置通知,在连接点方法前调用@Around环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法@After后置通知,在连接点方法后调用@AfterReturning返回通知,在连接点方法执行并正常返回后调用,要求连接点方法在执行过程中没有发生异常@AfterThrowing异常通知,当连接点方法异常时调用 使用自定义的注解

这里使用普通的SpringBoot来使用注解,创建一个Service,在里面使用注解,然后才控制层调用

//服务层 @Service public class TestService { @MyAnn public Map test(){ Map map=new HashMap(); map.put("t1","我是在Service设置的值"); return map; } } //控制层 @RestController public class Test2 { private Logger logger= LoggerFactory.getLogger(Test2.class); @Autowired private TestService testService; @GetMapping("/test") public String test(String id){ Map s=testService.test(); logger.info("控制层输出:{}",s.get("s1")); return "sccess"; } } 复制代码 输出 com.example.demo.aop.MyAnnAop : AfterReturning通知开始-获取数据:{t1=我是在Service设置的值} com.example.demo.web.Test2 : 控制层输出:我是在AOP中添加的新值 复制代码 注意事项

上面那样使用注解是没问题的,但是如果是下面这样使用,AOP就会失效

@RestController public class Test2 { private Logger logger= LoggerFactory.getLogger(Test2.class); @Autowired private TestService testService; @GetMapping("/test") public String test(String id){ Map s=this.test2(); logger.info("控制层输出:{}",s.get("s1")); return "sccess"; } @MyAnn public Map test2(){ Map map=new HashMap(); map.put("t1","我是在控制层设置的值"); return map; } } 复制代码 输出 com.example.demo.web.Test2 : 控制层输出:null 复制代码

这是应为内部方法调用,调用的是具体方法,并没有调用使用AOP后生成的代理方法

具体参考资料:

blog.csdn.net/Daybreak120… blog.csdn.net/u013151053/… zhewuzhou.github.io/2018/09/01/…


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3