@SpringBootApplication
标明启动类的注释,也就是标明项目程序入口,实际上集成了非常多的注释
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
@Data、@AllArgsConstructor、@NoArgsConstructor
这几个都是由Lombok库提供的(可以在idea下载插件,假设用maven管理需要在pom.xml里引入),@Data修饰类会生成getter、setter以及equals()、hashCode()、toString()等方法。@NoArgsConstructor、@RequiredArgsConstructor、@AllArgsConstructor修饰类的话可以制定构造函数,不用自己写了。
@Autowired
自动装配对象的,可以标注在属性上、方法上和构造器上
具体来说,参考了这篇,假设标注在属性上,那么会自动注入Bean对象,默认是按照类型注入的,但假设此时Car为接口,很有可能不止一个类实现了接口,就会报错,Spring并不知道应当引用哪个实现类。可以再加一个@Qualifier(“BMW”)注释,代表是注入BMW实现的Car接口类。
@Service
public class CarFactory
{
@Autowired
private Car car;
public String toString()
{
return car.carName();
}
}
但是官方不推荐在属性上标注@AutoWired,因为类成员的初始化顺序不同,静态成员 ——> 变量初始化为默认值——>构造器——>为变量赋值。如果标注在属性上,则在构造器中就不能使用这个属性(对象)的属性和方法。所以推荐在构造器上标注@AutoWired
@Component、@Controller、@Service、@Repository
这个博文讲的不错,本质上@Controller、@Service、@Repository本质都是@Component,即Spring容器中的一个组件。因为@Controller、@Service、@Repository实际上都被@Component注释了。在Spring源码中,注解会一级一级向上递归搜索,搜索所有的注解信息,即被以上注解注解的类在Spring看来都会包含@Component注解。
- @Component:通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component
注解标注。 - @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
- @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
- @Controller : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。
// 以下都是简略版代码
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Component
public @interface Repository {
@AliasFor(annotation = Component.class)
String value() default "";
}
那么问题来了,假设都相同的话,那为啥不直接用@Component还要分这么多?
相信做过java web的都知道MVC的概念,都知道一个基于MVC的java web项目一般可以简单划分为:Controller、Service、Dao、Util等,如果给Controller、Service、Dao都使用@Component那么不利于逻辑分层,添加这三个注解的主要目的就是为了逻辑分层,无论开发者给Controller命名为XxxYyyZzz还是AaaBbbCcc,只要注解有@Controller,那么可以理解为祖传代码的意思就是这一块就是Controller层。
@PostConstruct
@PostConstruct该注解被用来修饰一个非静态的void()方法。
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。
通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
所以经常用来做一些初始化的操作,但是呢,这个初始化操作却又依赖于依赖注入,那么久无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
比如一个策略map,HashMap<String, Strategy>,strategy是具体的对象,由依赖注入。然后立即初始化这个map,后续可以根据名字找策略对象了
@Configuration
通常是一些配置文件的注释,内含一些定义的常量之类的,可能是公司的一些工具网站的键值对的键名。也就直接自动生成Bean了,不用手动配置xml文件。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
@Value
可以读取application.yml中的一些配置信息
@RestController
@RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值以 JSON 或 XML 形式写入HTTP 响应体(Response)中,以json为多,是 REST 风格的控制器。因为纯@Controller基本不用了,它是对应一个前后端不分离的情况。
@Valid注解是对传参的格式的验证,验证失败会抛出MethodArgumentNotValidException
@RestController
@RequestMapping("/app")
public class AppController {
@PostMapping("/chat/submit")
public SseEmitter submit(@RequestBody @Valid Param param) {
// HttpResp应该是你自己写的一个类,包含你和前端的对齐的消息格式体
return HttpResp(func(param));
}
}
@Valid以及一些常用的验证性注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Param {
@NotNull(message = "classId 不能为空")
private String classId;
@Size(max = 33)
@NotNull(message = "name 不能为空")
private String name;
@Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围")
@NotNull(message = "sex 不能为空")
private String sex;
@Email(message = "email 格式不正确")
@NotNull(message = "email 不能为空")
private String email;
}
@Builder
可以简化builder(创建型)设计模式,例如考虑一个 User 类,包含 name、age 和 email 这三个字段。如果我们希望通过 Builder 模式创建 User 对象,那么可以这样做:
import lombok.Builder;
import lombok.ToString;
@Builder
@ToString
public class User {
private String name;
private int age;
private String email;
}
然后,我们可以通过下面的方式来创建 User 对象:
User user = User.builder()
.name("Tom")
.age(25)
.email("tom@example.com")
.build();
可以看出Lombok 生成了一个名为 builder 的静态方法,以及 name,age 和 email 的链式设置方法,最后通过 build 方法来构建 User 对象。
@TableName、@TableId
绑定某个类与数据库中的表,还可以指定主键以及其自增。
@Data
@AllAragsConstructor
@NoArgsConstructor
@TableName("t_app_record")
public class Record {
@TableId(type-IdType.AUTO)
private String id;
private String data;
}
@Mapper
这种一般都是把数据库内的数据映射上去了
@Mapper
public interface AppMapper extends BaseMapper<Record >