# Spring常用注解 ### @SpringBootApplication @SpringBootApplication=@Configuration+@EnableAutoConfiguration+@ComponentScan,其中扫描包的范围为启动类所在包和子包,不包括第三方的 jar 包 标注在某个类上说明这个类是 SpringBoot 的启动类,SpringBoot 运行这个类的 main 方法来启动 SpringBoot 应用。 ### @Mapper 作用:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类 添加位置:接口类上面 ```java @Mapper public interface UserMapper extends BaseMapper { } ``` 如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper 注解,比较麻烦,解决这个问题可以用@MapperScan ### @MapperScan 作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类,不必给所有的 Mapper 类单独加上`@Mapper`注解了 添加位置:是在 Springboot 启动类上面添加 ### @Controller 在 SpringMVC 中提供了一个非常简便的定义 Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是 Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义 URL 请求和 Controller 方法之间的映射,这样的 Controller 就能被外界访问到。 ### @RequestMapping 可以使用`@RequestMapping` 来映射`URL`到控制器类,或者是到`Controller`的处理方法上 参数介绍: - `value`:定义处理方法的请求的 URL 地址 - `method`:定义处理方法的 http method 类型,如 GET、POST 等,缺省时可以处理任何形式的 http 请求 - `params`:定义请求的 URL 中**必须包含**的参数。或者不包含某些参数 - `headers`:定义请求中 Request Headers 必须包含的参数。或者不包含某些参数 `@RequestMapping`有两种标注方式,一种是标注在类级别上,一种是标注在方法级别上。 - 标注在方法上时,value 表示访问该方法的 URL 地址。 - 标注在类上时,value 相当于一个命名空间,即访问该 Controller 下的任意方法都需要带上这个命名空间。 更多示例请参考:[Spring MVC @RequestMapping 注解详解)](https://www.cnblogs.com/caoyc/p/5635173.html) **示例: @Controller+@RequestMapping** 调用`localhost:8080/index/`返回`static`目录下的`index.html` ```java @Controller public class TestController { @RequestMapping("index") public String getSomething() { return "index"; } } ``` `application.properties`配置 ```properties spring.mvc.view.prefix=/ spring.mvc.view.suffix=.html ``` #### 使用 freemarker 解析 html 数据 调用地址: http://localhost:8080/test/data/ ```java @Controller @RequestMapping(value ="/test/") public class TestController { public static final String PAGE_1="view"; // staic文件夹下的view.html @RequestMapping("/data/") public ModelAndView data() { ModelAndView view = new ModelAndView(PAGE_1); view.addObject("str1","数据1"); view.addObject("str2","数据2"); return view; } } ``` `view.html`: ```html 我的页面

渲染数据

${str1}


${str1}


``` `application.properties`配置 ``` spring.freemarker.suffix=.html spring.freemarker.template-loader-path=classpath:/static/ ``` ### @RequestParam @RequestParam 注解用于绑定请求参数值,在处理方法入参处使用@RequestParam 注解可以把请求参数传递给请求方法。 调用地址: http://localhost:8080/params/?id=100 ```java @Controller @RequestMapping("/params") public class ParamController { public static final String PAGE = "param"; @RequestMapping public ModelAndView testParams(@RequestParam(value = "id",defaultValue = "1000") Integer id, @RequestParam(value = "type",required = false) String type){ if (null != type && type.equals("ok")) { // 注意type.equals("ok")放前面会抛出空指针异常 System.out.println("ok"); } ModelAndView view = new ModelAndView(PAGE); view.addObject("id",id); return view; } } ``` ### @PathVariable @PathVariable 映射 URL 绑定的占位符,通过@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中 调用地址: http://localhost:8080/params/path/100/ ```java @Controller @RequestMapping("/params") public class ParamController { public static final String PAGE = "param"; @RequestMapping("/path/{id}") public ModelAndView testPath(@PathVariable Integer id){ ModelAndView view = new ModelAndView(PAGE); view.addObject("id",id); return view; } } ``` ### @RestController @RestController 相当于@Controller+@ResponseBody,返回 json 或者 xml 格式数据。 @ResponseBody 注解的作用是将 Controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据。 ### @GetMapping 注解用于处理 HTTP GET 请求,并将请求映射到具体的处理方法中,相当于`@RequestMapping(method=RequestMethod.GET)` ### @DeleteMapping 注解用于处理 HTTP DELETE 请求,并将请求映射到具体的处理方法中,相当于`@RequestMapping(method=RequestMethod.DELETE)` ### @PutMapping 注解用于处理 HTTP PUT 请求,并将请求映射到具体的处理方法中,相当于`@RequestMapping(method=RequestMethod.PUT)` ### @PostMapping 注解用于处理 HTTP POST 请求,并将请求映射到具体的处理方法中,相当于`@RequestMapping(method=RequestMethod.POST)` ### @Component @Component 注解用于标注一个普通的组件类,它没有明确的业务范围,只是通知 Spring 被此注解的类需要被纳入到 Spring Bean 容器中并进行管理。一般用于重复使用的封装类。 ### @Service `@Service`注解是`@Component`的一个特例,它用于标注业务逻辑类。与`@Component`注解一样,被此注解标注的类,会自动被 Spring 所管理。 ### @Autowired @Autowired 注解用于标记 Spring 将要解析和注入的依赖项。因此可用于获取 Bean。此注解可以作用在构造函数、字段和 setter 方法上。 作用于构造函数中 ```java @RestController public class UserController { private UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } } ``` 作用于字段上 ```java @RestController public class UserController { @Autowired private UserService userService; } ``` 作用于 setter 方法上 ```java @RestController public class UserController { private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } } ``` ### @Resource **@Resource = @Autowired+@Qualifier**。功能上和@Autowired 类似,具体区别如下: - 如果接口实现只有一个,那么用@Autowired 就可以了,也不需要指定名字。 - 如果接口有多个实现,那么,用@Resource,并指定实现类的名字,注意 value 的首字母要小写 - 或者使用@Autowired+@Qualifier,@Qualifier 中指定对应的实现类名字,注意 value 的首字母小写 ### @Configuration+@Bean 将未使用`@Service`注解的两个`Service`接口实现类改为手动注入 Bean。 ```java @Configuration public class myBeans { @Bean // 实现类是AdminServiceImpl,现在没有使用@Service注解,该为手动注入 public UserService adminServiceImpl() { return new AdminServiceImpl(); } @Bean // 实现类是UserServiceImpl public UserService userServiceImpl() { return new UserServiceImpl(); } } ``` ### @Value 用于读取配置文件中的自定义字段值 下面是一些在`application.properties`中自定义字段 ``` my.page=1 local.username=admin local.password=admin123 ``` 读取字段值,返回对应的`json`数据 ```java @RestController public class UserController { @Value("${local.username}") private String username; @Value("${local.password}") private String password; @Value("${my.page}") private Integer page; @GetMapping("/values/") public JSONObject getInfo() { JSONObject object = new JSONObject(); object.put("page",page); object.put("username",username); object.put("password",password); return object; } } ``` ### @ConfigurationProperties **绑定属性**,根据前缀(prefix)**批量导入**配置文件中的值 `application.properties`定义如下字段: ``` person.name=admin person.password=123123 person.sex=男 person.age=18 ``` 配合`@ConfigurationProperties(prefix = "person")`对`Person`类属性自动赋值 ```java @Component @ConfigurationProperties(prefix = "person") public class Person { // 字段名称必须一一对应 private String name; private String password; private String sex; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ``` {{< admonition >}} 如果上面的类不加`@Component`, 那就需要在启动类上添加注解`@EnableConfigurationProperties({Person.class})`来启用配置。 {{< /admonition >}} 调用`http://localhost:8080/person/`返回读取配置文件后的`person`对象的数据 ```java @RestController public class PersonController { @Autowired private Person person; @GetMapping("/person/") public Person getPerson() { return person; } } ``` **注意: 不能有多个类指定相同的前缀** **可能发生中文乱码问题** - `properties`文件中文乱码:修改`application.properties`的编码类型
{{}}
- 接口返回中文乱码:`properties`文件中配置字符编码格式 ``` # 编码设置为UTF-8 server.servlet.encoding.force=true server.servlet.encoding.charset=UTF-8 ``` 如果不想使用默认的配置文件,可以使用`@PropertySource`读取自定义配置文件 **注意:如果在 application.properties 中也定义了配置,会覆盖自定义配置文件中的字段值(白配置了!)** ``` @PropertySource(value = {"classpath:static/person.properties"}) ``` ### @ImportResource 虽然`SpringBoot`并不推荐我们继续使用 xml 配置,但如果出现不得不使用 xml 配置的情况,`SpringBoot`允许我们在入口类里通过注解`@ImportResource({"classpath:beans.xml"})`来引入`xml`配置文件。 > 当然,相比之下`SpringBoot`更推荐的依赖注入方式还是使用`@Configuration+@Bean` ```java @ImportResource(locations = {"classpath:beans.xml"}) // 导入Spring的配置文件让其生效 ``` ### lombok 提供的注解 - `@Data`: 注在类上,提供类的 get、set、equals、hashCode、canEqual、toString 方法 - `@AllArgsConstructor`: 注在类上,提供类的全参构造,参数顺序和属性在类中的顺序一致 - ` @NoArgsConstructor`: 注在类上,提供类的无参构造 - `@Setter`: 注在属性上,为属性提供 set 方法;注在类上,为所有属性提供 set 方法 - ` @Getter`: 注在属性上,提供 get 方法;注在类上,为所有属性提供 get 方法 - `@EqualsAndHashCode`:注在类上,提供对应的 equals、hashCode 和 canEqual 方法 - ` @Log4j/@Log4j2/@Slf4j`: 注在类上,提供对应的 Logger 对象,变量名为 log ### @Slf4j 不使用该注解前打印日志需要获取`Logger`对象 ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class UserController{ private static final Logger log = LoggerFactory.getLogger(UserController.class); pubulic void getLog() { log.info("xxx"); } } ``` 使用注解后 ```java @Slf4j public class UserController{ pubulic void getLog() { log.info("xxx"); } } ``` ### @Validated 对配置文件的数据字段进行校验 在`pom.xml`中导入依赖 ```xml javax.validation validation-api org.hibernate.validator hibernate-validator ``` 配置`Bean` ```java import org.hibernate.validator.HibernateValidator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; @Configuration public class ValidatorConfig { @Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() // 快速失败模式 .failFast(true) // .addProperty( "hibernate.validator.fail_fast", "true" ) .buildValidatorFactory(); return validatorFactory.getValidator(); } } ``` 配置文件`application.properties`内容如下: ``` student.id = 1 student.name = admin student.age = 5 ``` `Student`实体类 ```java @Data @AllArgsConstructor @NoArgsConstructor @ConfigurationProperties(prefix = "student") @Validated public class Student { private int id; private String name; @Max(value = 40,message = "最大值不能超过40") @Min(value = 10,message = "最小值不能小于10") private int age; } ``` 运行后age校验失败:
{{}}