spring boot系列------自定义注解

自定义注解,可能大家听起来要点陌生,但是作为一个web开发人员来说相比就不那么陌生吧。在我们java开发中我们经常能见到这些注解:

常见的注解:

jdk自带的注解:

1、@Override注解
用于重写父类的方法 或者是写接口实现类时用到该注解。
2、@Deprecated注解
用于表示该方法是一个过期的方法。
3、 @suppressWarnings注解
表示该方法在编译时自动忽略警告。

spring框架的注解:

1、@Component 组件,没有明确的角色
2、@Service 在业务逻辑层(service层)使用
3、@Repository 在数据访问层(dao层)使用
4、@Controller 在controller控制层使用
5、@Autowired 自动装配(默认根据类型注入,可直接在字段属性上或set方法上使用)
6、@Value 注入SpEL表达式
7、@Qualifier 限定描述符一般与@Autowired配合使用可找到唯一的一个bean对象


这些注解想必我们都用过吧ps(可能都没有仔细注意这个)。在我们spring boot这个框架中,其实受大家喜爱的原因就是将之前的配置化东西变成注解化,而我们用别人的注解的时候,直接参考着用法去用就是,不用知道他是如何运行的,但是我们知道什么时候需要用注解?注解能解决什么?
假设一个场景,公司要使用rbac来做权限管理,这样的话我们的权限是具体到每一个接口的,如果按照以前的思想我们需要在每一个接口里面去做判断,先判断用户的权限是否与这个接口一致,不一直就不让他继续下去,但是这样在每一个接口加这个真的好吗?
答案是不好,这时候就会使用到我们spring中最大的特性之一的方法就是aop,面向切面,可能大家会问自定义注解怎么又扯上aop呢?其实在spring boot中自定义注解的本质上是spring aop对自定义注解的支持。所以我们在spring boot中要实现自定义注解的时候要去了解一下aop,但是在开始我们写注解的第一步是先了解一下元注解,因为我们自定义注解是离不开这些元注解的
1、@Target
2、@Retention
3、@Inherited
4、@Documented
我们会主要讲解前面两个,后面两个会一笔带过

  1. @Target 注解

@Target注解:他的作用是将这个注解放在什么地方,比如类上、方法上、构造器上、变量上等,他的值是一个枚举类型的。
1、ElementType.CONSTRUCTOR:用于描述构造器
2、ElementType.FIELD:成员变量、对象、属性(包括enum实例)
3、ElementType.LOCAL_VARIABLE:用于描述局部变量
4、ElementType.METHOD:用于描述方法
5、ElementType.PACKAGE:用于描述包
6、ElementType.PARAMETER:用于描述参数
7、ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
也就是说你使用这个注解的时候是告诉你这个注解可以放在什么位置。

  1. @Retention 注解

@Retention 注解:他的作用是为了说明这个注解的生命周期,在注解中有三个生命周期
1、RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
2、RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
3、RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
我们在自定义使用过程中基本上使用的是第一种
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
我们也将完了这几个元注解,接下来我们要新建一个注解
首先在esclipse中新建一个annimation,然后会生成一个@类名的注解类,然后在添加上元注解,如下所示


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Test {
    String value();
}

这个时候我们的注解就已经搞定了,接下来就是实现他的业务逻辑了。而实现他的业务是以aop的方式去实现的。
在实现之前我们先去了解一下几个aop常用的注解
aop常用的注解
1、@Aspect作用是把当前类标识为一个切面供容器读取
2、@before标识一个前置增强方法,相当于BeforeAdvice的功能
3、@after final增强,不管是抛出异常或者正常退出都会执行
4、@Pointcut定义切点
5、@Around
ps(这里没有按照先后顺序来)
这些注解就不一一讲解了

@Aspect
@Component
public class OperateAspect {

         @Pointcut("@annotation(com.junge.annotation.Test)")
         public void annotationPointCut() {

         }
//       ​
        @Before("annotationPointCut()")
        public void before(JoinPoint joinPoint){
           MethodSignature sign =  (MethodSignature)joinPoint.getSignature();
           Method method = sign.getMethod();
           Test annotation = method.getAnnotation(Test.class);
           System.out.print("打印:"+annotation.value()+" 开始前");
        }    
        @Around("annotationPointCut()")
        public Object advice(ProceedingJoinPoint joinPoint){
            System.out.println("通知之开始");
            Object retmsg=null;
            try {
                 retmsg=joinPoint.proceed();
                System.err.println("++++++++"+retmsg);
            } catch (Throwable e) {
                e.printStackTrace();
            }
            System.out.println("通知之结束");
            return retmsg;
        }

        @After("annotationPointCut()")
        public void after() {
             System.out.println("after方法执行后");
        }

}

这样就实现了一个简单的自定义注解,如果你有自己的业务要写的话,你可以在某个方法里面写你的业务,比如记录操作日志,那么你就可以在@after方法里面写你的业务层代码。
然后在你的接口上面可以加上@Test注解

 */
@SpringBootApplication
@RestController
@EnableAspectJAutoProxy
public class App 
{
    public static void main( String[] args )
    {
//        System.out.println( "Hello World!" );
        SpringApplication.run(App.class, args);
    }

    @RequestMapping("/")
    @Test("测试")
    public List<String> getById() {
//      haha();
        System.err.println("o+++++++++++++++++");
        List<String> list=new ArrayList<String>();
        list.add("1");
        list.add("qwe");
        list.add("asd");
        return list;
    }

这样自定义注解就完成了,其实最主要的是我们要导入我们spring boot支持aop的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

到这里为止,我们的自定义注解就已经搞定。
在aop中执行顺序如下所示,ps(去网上找了个图)
这里写图片描述
注意事项:
1、首先就是注解里面的参数,基本类型以及string和class,不支持map、list这种类型的
2、只能用public和default来修饰,不能用其他的比如抛出异常等
3、不能有传参数的,即String value(String a),这种类型的。
4、如果只有一个参数的话,那么默认就是用value方法名称

猜你喜欢

转载自blog.csdn.net/u013825231/article/details/80468167