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
mvc的controller*/
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 flect.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 = Annotation (FieldChuan.class);
System.out.println ("annotation1 = "+ lumnName ());
}
}
springboot的常⽤注解
@Controller
表明这是Controller类,MVC层中的Controller层。
⽤户前端发起请求,中央调度器DispatcherServlet就会根据处理器映射器到标注了@Controller注解的类,从⽽到相应的处理器⽅法来处理请求。
@Serveice和@Component和@Repositry和@Controller
@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"";
//...
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论