admin管理员组

文章数量:1794759

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

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

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

从源码上手,一通百通。

文章目录
        • 前话
          • 什么是注解?
          • 注解如何起作用?
        • springboot的常用注解
          • @Controller
          • @Serveice和@Component和@Repositry和@Controller
          • @ReponseBody
          • @RestController使用
          • @ConfigurationProperties
        • 总结

前话

学习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 张川 * @博客 blog.csdn/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 张川 * @博客 blog.csdn/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自动装配原理

本文标签: 注解并从原理常用SpringBoot