springboot常用注解@Controller等注解的使用并从原理解析

springboot常用注解使用及原理解析

从源码上手,一通百通。

前话

学习springboot的注解之前,先了解注解是个什么东西,有什么用?并且注解是如何生效的?

什么是注解?

注解本质上是一个接口。

java自带的几个注解,叫元注解,元注解可以用来标识给其他注解。

0.元注解

元注解主要学习三个。

@Target
@Retention
@Documented

@Target(ElementType.TYPE)

表明该注解用在哪儿?方法上还是类上还是属性值上。

@Target括号里面的值,可以填的有:

public enum ElementType {
    /** 类,接口上 */
    TYPE,

    /** 表明可以用于属性上 */
    FIELD,

    /** 方法上 */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /**构造器上 */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** 包上 */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Retention(RetentionPolicy.RUNTIME)

表明注解生效的范围,这里是运行时生效,也有源码时生效,不过通常是运行时生效。

@Documented

文档~表明可以用于什么文档啥的,没啥用。

1.自定义注解

package Annoation;

import java.lang.annotation.*;

@Documented
@Retention (RetentionPolicy.RUNTIME)//运行时生效
@Target (value = ElementType.TYPE)//可以在方法上 在字段上使用等
public @interface MyAnnoation {
    String value() default  "a class";//值
}

与定义接口一样,使用关键字@interface,差别是注解里面声明的是属性值,而不是方法。

上述的注解MyAnnoation可以用在类上并且运行时生效。

注解如何起作用?

注解通过反射生效,通过反射我们可以得到不管是类的所有注解,并且得到注解的值,根据这些值我们就可以进行相应的操作。

例如springboot里面中央调度器DispatcherServlet就是根据标注了注解@Controller的类找相应的处理器HandleServlet。

测试:

FiledChuan注解:

package Annoation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 * @description:
 * @author java川
 * @date  2019/3/5
 * @param 
 * @throws 
 * @return 
 */
@Retention(RetentionPolicy.RUNTIME)//运行时生效
@Target(ElementType.FIELD)//用在参数上
public  @interface  FieldChuan{
    String columnName();//列名

}

User类:

package pojo;

import Annoation.FieldChuan;
import Annoation.MyAnnoation;
/**
 * @Author 张川
 * @博客 https://blog.csdn.net/weixin_43919632
 * @Date 2019-03-5-14:37
 */
@MyAnnoation(value = "User.class")
public class User {
    @FieldChuan(columnName = "db_name")
    public String name;

    public User(String name) {
        this.name = name;
    }


    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

测试方法:

import Annoation.FieldChuan;
import Annoation.MyAnnoation;
import pojo.User;

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

/**
 * @Author 张川
 * @博客 https://blog.csdn.net/weixin_43919632
 * @Date 2021-03-05-14:37
 */
public class MainTest {


    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //反射获取User字节码Class
        Class cl = Class.forName ("pojo.User");
        Class cl2 = new User ().getClass ();
        //反射获得类的注解
        Annotation[] annotations = cl.getAnnotations ();
        for (Annotation annotation : annotations) {
            System.out.println ("获得注解=====》" + annotation);
        }
        //反射获得注解的值
        MyAnnoation annotation = (MyAnnoation) cl.getAnnotation (MyAnnoation.class);
        System.out.println ("annotation.value () = " + annotation.value ());


        //获得属性的注解的值
        Field name = cl.getDeclaredField ("name");
        FieldChuan annotation1 = name.getAnnotation (FieldChuan.class);
        System.out.println ("annotation1 = " + annotation1.columnName ());


    }

}

springboot的常用注解

@Controller

表明这是Controller类,MVC层中的Controller层。

用户前端发起请求,中央调度器DispatcherServlet就会根据处理器映射器找到标注了@Controller注解的类,从而找到相应的处理器方法来处理请求。

@Serveice和@Component和@Repositry和@Controller

👉解析注解@Compnent工作原理

@ReponseBody

从以下源码,写的注释中知道:

这个疏解就是返回值到前端,而不会被视图解析器解析成视图。

@Target({ElementType.TYPE, ElementType.METHOD})

可以使用在类和方法上。

/**
 * Annotation that indicates a method return value should be bound to the web
 * response body. Supported for annotated handler methods.
 *
 * <p>As of version 4.0 this annotation can also be added on the type level in
 * which case it is inherited and does not need to be added on the method level.
 *
 * @author Arjen Poutsma
 * @since 3.0
 * @see RequestBody
 * @see RestController
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {

}
@RestController使用
@RestController用在类上,标注类里面的所有方法不用被视图解析解析,而是直接返回数据。

该注解的源码:

可以看到该注解集成两个@Controller和@ReponseBody注解。表明该类就是一个接口类,不会被视图解析器解析,而是直接返回数据。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

   /**
    * The value may indicate a suggestion for a logical component name,
    * to be turned into a Spring bean in case of an autodetected component.
    * @return the suggested component name, if any (or empty String otherwise)
    * @since 4.0.1
    */
   @AliasFor(annotation = Controller.class)
   String value() default "";

}
@ConfigurationProperties

源码:

/**
 * Annotation for externalized configuration. Add this to a class definition or a
 * {@code @Bean} method in a {@code @Configuration} class if you want to bind and validate
 * some external Properties (e.g. from a .properties file).
 * <p>
 * Binding is either performed by calling setters on the annotated class or, if
 * {@link ConstructorBinding @ConstructorBinding} is in use, by binding to the constructor
 * parameters.
 * <p>
 * Note that contrary to {@code @Value}, SpEL expressions are not evaluated since property
 * 
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
    String prefix() default "";
    //...
    
}

从注释中:

这是一个额外扩展的注解,可以加到一个定义了的类(放到容器),用于在你想要绑定的额外的一些属性上,通过创建propertes文件的形式。

绑定是否生效时通过setter方法或者构造器的方式,因此我们在使用注解@ConfigurationProperties的时候,这个类要创建构造器或者setter方法,否则不能生效。

可以通过@value注解方式,使用spel表达式从properties文件中取值赋值给相应的属性。

还有重要的一点:我们要使用@EnableAutoConfiguration放在主类上,用于开启属性自动配置。

EnableXXXX什么的,都是用于开启什么服务之类的~。

总结

注解呢,其实只要了解了本质,知道看它的源码就能明白它到底是个什么东西,知道怎么使用。

java中呢,能够通过反射来获取注解上的一些东西,从而能根据注解上的东西做不同处理。

更多相关文章👉@Component解析原理

​ 👉spingMVC请求处理过程

​ 👉springboot自动装配原理

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页