在 Spring Boot 开发中注解(Annotation)占有重要的地位。注解为在代码中添加信息提供了一种形式化的方法,通过注解可以很方便地在代码中某个地方使用被注解的对象。注解常见的作用包括生成文档、跟踪代码依赖性和替代配置文件、在编译时进行格式检查(如 @Override 放在方法前)等。
本文介绍 Spring Boot 注解以及和 Spring Boot 注解密切相关的 Java 注解、Spring 注解等内容。
JRE 的库包 java.lang.annotation 代码中包括注解相关的接口、类等内容。接口 java.lang.annotation.Annotation 是所有自定义注解自动继承的接口,不需要定义时指定, 类似于所有 JAVA 类都自动继承的 Object 类。
注解是一系列元数据,它利用元数据来解释、说明程序代码(即被注解的对象)。但是,注解不是所标注的代码的组成部分。注解对于代码的运行效果没有直接影响。注解的作用包括:
在了解注解具体语法之前,可以将注解看成一张标签。与接口和类一样,注解也是一种类型。注解是自 JAVA 1.5 开始引入的概念,它允许开发者定义自己的注解类型和使用自定义的注解。注解通过关键词 @interface 进行定义。
public @interface TestAnnotation {
}
上例中的代码自定义了一个名字为 TestAnnotation 的注解,该注解自动继承了类 java.lang.annotation.Annotation。创建了自定义注解后,就可以使用自定义的注解。注解的使用方法如下所示:
@TestAnnotation
public class Test {
}
上例创建了一个类 Test,并在类定义的上方加上了 @TestAnnotation 注解,这意味着用 TestAnnotation 注解了类 Test。
要想更好地使用注解,还需要理解元注解。元注解是加到注解上的注解,它的目的是解释、说明其他普通注解。元注解有 @Retention、@Documented、@Target、@Inherited、@Repeatable 共五种。
@Retention 应用到一个注解时,说明该注解的存活时间。它的取值包括:
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
以上表示注解 TestAnnotation 可以在程序运行时被获取到。
@Documented 表示注解内容会被 Javadoc 工具提取成文档,文档内容会因为注解内容的不同而不同。
@Target 表示注解用于什么地方,如类型、方法和域等。元注解 @Target 的取值包括:
@Inherited 表自动继承,即被 @Inherited 注解过的注解作用于父类后,子类会自动继承父类的注解。示例代码如下:
// 定义注解
@Inherited
@Retention(RetentionPoilcy.RUNTIME)
@interface Test { }
// 在父类中添加注解
@Test
public class A { }
// 子类 B 虽然没有明确给出注解信息,但是它会继承父类 A 中的注解 @Test
public calss B extends A { }
@Repeatable 是在 JAVA 1.8 中引入的注解,其应用的示例代码如下所示。Persons 可以被看作是一张总标签,上面贴满了 Person 这种同类型但内容不一样的标签。于是,可以同时给 SuperMan 贴上画家、程序员、产品经理等标签(即加上三个注解)。
// Persons 使用数组存放注解的容器注解,它里面必须要有一个 value 属性,即数组
@interface PerSons {
Person[] value();
}
// 可以重复、多次应用 Persons 注解
@Repeatable (Persons.class)
@interface Person {
String role default "";
}
// 不同属性的Person注解
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan {
}
注解中可以拥有属性(也叫成员变量),示例代码如下所示。表示自定义的注解 TestAnnotation 拥有 id 和 msg 两个属性,返回类型分别为 int 和 String。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id();
String msg();
}
使用注解时,应该给属性赋值。属性的赋值方法是在注解后免得括号内以 “属性=取值” 的形式进行的,多个属性的赋值之间用逗号隔开,示例如下。需要注意的是,注解中属性的类型只能是 8 中基本数据类型和类、接口、注解及它们的数组。
@TestAnnotation(id=3, msg="hello world")
public class Test {
}
注解中属性可以有默认值,默认值需要用关键词 default 指定,示例代码如下所示。注解 TestAnnotation 中属性 id 的默认值被指定为 -1,属性 msg 的默认值被指定为 “Hi”。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
public int id() default -1;
public String msg() default "Hi";
}
加入指定了属性默认值,可以不用再在注解 TestAnnotation 后面的括号内对属性进行赋值。
如果注解只有一个属性时,应用这个注解时则可以省略属性名而将属性值直接填写到注解后面的括号内。
如果注解没有任何属性,应用这个注解时注解后面的括号则可以省略。
在 java.lang 包下,Java 预先提供了 @Deprecated、@SuppressWarnings、@Override、@SafeVarargs、@FunctionalInterface 共五个注解。
// @Override 可以帮忙检查方法的正确性
@Override
public String toString() {...} // 这是子类方法正确的写法
// 下面子类方法是错误的,有 @Override,系统可以帮忙检查出 tostring 的拼写错误
@Override
public String tostring() {...}
// 下面子类方法是错误的,由于没有 @Override,系统不会帮助检查出 tostring 的拼写错误
public String tostring() {...}
Spring 容器通过把 JAVA 类注册成 Bean 的方式来管理 JAVA 类。把 JAVA 类变成 Bean 有两种方式:一种方式通过 XML 配置把 JAVA 类注册成 Bean; 另一种方式通过注解的方法将 JAVA 类注册成 Bean。利用不同的注解可以将 JAVA 类注册成不同的 Bean。相对于 XML 配置,注解方法更加方便、便捷。于是,越来越多的工具都支持用注解进行配置而放弃 XML 配置。
可以将注解 @Component 放在类的前面,该类被标注成 Spring 的一个普通 Bean。
注解 @Controller 标注一个控制器组件类,它被用来实现自动检测类路径下的组件并将组件自动注册成 Bean。例如,使用 @Controller 注解标注 Java 类 UserAction 后,就表示要把类 UserAction 标注成 Bean 并交给 Spring 容器管理。如果不指定 Bean 的名字,按照约定该 Bean 会被命名为 userAction。也可以在注解后面的括号内指定 Bean 的名字,例如采用 @Controller(value=“UA”) 或者 @Controller(“UA”) 的方法来指定 Bean 的名字为 UA。
注解 @Service 标注一个业务逻辑组件类。例如,类 Action 需要使用 UserServiceImpl 实例时,可以用 @Service(“uaerService”) 注解告诉 Spring 创建好一个 UserServiceImpl 实例 (名字为 userService)。Spring 创建好 userService 之后可以将其注入给 Action,Action就可以使用该 UserServiceImpl 实例了。
注解 @Repository 标注一个 DAO 组件类。可以用 @Repository(value=“userDao”) 注解告诉 Spring 创建一个 UserDao 实例(名字为 userDao)。当 Service 需要使用 userDao 时,可以用 @Repository(name=“userDao”) 注解告诉 Spring 把创建好的 userDao 注入给 Service。
注解 @Autowired 被用来实现自动装配,@Autowired 可以被用来标注成员变量、方法、构造函数等对象。虽然 @Autowired 的标注对象不同,但是都会在 Spring 初始化 Bean 时进行自动装配。使用 @Autowired 可以使 Spring 容器自动搜索符合要求的 Bean,并将其作为参数注入。
@Autowired 是根据类型进行自动装配的,示例代码如下所示。如果 Spring 上下文中存在多个同类型的 Bean 时(如有两个类都实现了 EmployeeService 接口),Spring 不知道应该绑定哪个实现类,就会抛出 BeanCreationException 异常。如果 Spring 上下文中不存在某个类型的 Bean 时,也会抛出 BeanCreationException 异常。
注解 @Autowired 的应用代码示例:
// 接口 Employeeservice 声明
public interface EmployeeService {
public EmployeeDto getEmployeeById(Long ld);
}
// 两个实现类 EmployeeServiceImpl 和 EmployeeServiceImpl1
@Service("service")
public class EmployeeserviceImpl implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
Service("service1")
public class EmployeeServiceImpll implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmpioyeeDto();
}
}
// 调用接口实现类
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
@Autowired//此注解处会出错,因为有两个实现类,而不知道绑定哪一个
EmployeeService employee5ervice;
@RequestMapping(params = "method=showEmplayeeInfo")
public void showEmplayeeInfo(HttpServletRequest request, HttpservletRespcnmresponse, EmployeeDto dto) {
... // 代码省略
}
}
可以使用 @Qualifier 配合 @Autowired 来解决异常 BeanCreationlException,示例代码如下:
// 接口 Employeeservice 声明与上例一致
// 接口的两个实现类 EmployeeserviceImpl 和 EmployeeserviceImpl1 与上例一致
// 接口实现类的调用
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
@Autowired
@Qualifier( "service") // 新增加语句,指定调用第一个接口实现类
EmployeeService employeeService;
@RequestMapping(params = "method=showEmplayeeInfo")
public void showEmplayeeInfo(HttpServletRequest request, HttpservletRespcnmresponse, EmployeeDto dto) {
... // 代码省略
}
}
注解 @Resource 可用于标注一个对象的 SET 方法。注解 @Resource 的作用相当于 @Autowired,只不过 @Autowired 按类型自动注入,而 @Resource 默认按名字自动注入。JSR-250 标准推荐使用通用注解 @Resource 来代替 Spring 专有的 @Autowired 注解。
JSR(Java Specification Requests, Java规范提案) 是指向 JCP(Java Community Process) 提出新增一个标准化技术规范的正式请求。任何人都可以提交 JSR,以向 Java 平台增添新的 API 和服务。JSR 已成为 Java 界的一个重要标准。从 Spring 2.5 开始,Spring 框架的核心支持 JSR-250 标准中的注解 @Resource、注解 @PostConstruct 和注解 @PreDestroy。
@Resource 有两个属性比较重要,分别是名字 name 和属性 type。Spring 将 @Resource 注解 name 属性解析为 Bean 的名字,而将 type 属性解析为 Bean 的类型。如果使用 name 属性,则使用按名字自动注入的注入策略,而使用 type 属性时则使用按类型自动注入的注入策略。如果既不指定 name 属性也不指定 type 属性,则通过反射机制使用按名字自动注入的注入策略。@Resource 使用按名字自动注入的注入策略时,与使用 @Qualifier 明确指定 Bean 的名称进行注入作用相同。在众多相同的 Bean 中,优先使用 @Primary 注解的 Bean。这和 @Qualificr 有点区别,@Qualificr 指的是使用哪个 Bean 进行注入。
注解 @PostConstruct 和注解 @PreDestroy 都是 JSR-250 标准的注解。标注了 @PreDestroy 的方法将在类销毁之前调用,@PostConstruct 注解过的方法将在类实例化后调用。
从 Spring 3.0 开始,Spring 开始支持 JSR-330 标准的注解。JSR-330 中,@Inject 和 Spring 中的 @Autowired 的职责相同,@Named 和 Spring 中的 @Component 的职责类似。
可以用注解 @Scope 来定义 Bean 的作用范围 (称为作用域),也可以通过在 XML 文件中设置 Bean 的 scope 属性值来实现这一目的。@Scope 注解的值可以是 singleton、prototype、request、session、global scssion 等作用域,默认是单例模式,即 scope=“singleton”。其中:
Portlet 的请求处理分为 action 阶段和 render 阶段。在一个请求中,action 阶段只执行一次,但是 render 阶段可能由于用户的浏览器操作而被执行多次。Portlet 规范定义了global session 的概念,它被所有构成某个Portlet Web 应用的各种不同 Portlet 所共享。在 global session 中定义的 Bean 被限定Portlet 全局会话 (global scssion) 的生命周期范围内。如果在 Web 中使用 global session 来标识 Bean,那么 Web 会自动当成 session 类型来使用。
JSR-330 默认的作用域类似 Spring 的 prototype, ISR-330 标准中的 Bean 在 Spring 中默认也是单例的。如果要使用非单例的作用域,开发者应该使用 Spring 的 @Scope 注解。JSR-330 也提供了一个 @Scope 注解,然而,这个注解仅仅在用来创建自定义的作用域时才能使用。
注解 @RequestMapping 为类或方法指定一个映射路径,可以通过指定的路径来访问对应的类或方法,应用示例如下例所示。其中,userid 值通过 @PathVariable 注解方法进行绑定。注解 @PathVariable 主要用来获取单一的 URI 参数,如果想通过 URI 传输一些复杂的参数,则要考虑使用注解 @MatrixVariable。@MatrixVariable 的矩阵变量可以出现在 URI 中任何地方,变量之间用分号(;)分隔。@MatrixVariable 默认是不启用的,启用它时需要将 enable-matrix-variablcs 设置为 true。
注解 @RequestMapping 的应用代码示例。
@RequestMapping(value="/getName/{userid}", method = RequestMethod.Get)
public void login(@Pathvariable String userid, Model mcdel){
}
注解 @RequestParam 将请求中带的值赋给被注解的方法参数。如下例所示,把请求中的值 username 赋给方法中 username 这个参数。属性 required 代表参数是否必须赋值,默认为 true;当不能确定请求中是否有值可以赋给参数时,就必须把属性 required 设置为 false。
public void login(@RequestParam(value="username" required="true") String username){
}
不管是 HTTP 请求还是 HTTP 响应都是通过报文传输的,而报文都有头和正文。头包含服务端或者客户端的一些信息,用来表明身份、提供验证或限制等。正文是要传递的内容。注解 @RequestBody 把请求报文中的正文自动转换成绑定给方法参数的变量字符串。响应请求时,@ResponseBody 将内容或 Java 对象转换成响应报文的正文返回。当返回的数据不是 HTML 标记页面 (视图) 而是其他某种格式数据 (如JSON、XML等) 时,才使用 @RequestBody 注解。
注解 @Param 表示对参数的解释,一般写在注释里面。
注解 @JoinTable 表示 Java 类和数据库表的映射关系,也可以标识列的映射、主键的映射等。
注解 @Transational 是 Spring 事务管理的注解。被 @Transational 注解的方法或类自动被注册成事务,接受 Spring 容器的管理。
注解 @Syschronized 表示实现 Java 同步机制,用它作注解相当于加同步锁。
注解 @ModelAttribute 声明在属性上,表示该属性的值来源于 model 里 queryBean,并被保存到 model 里。注解 @ModelAttribute 声明在方法上,表示该方法的返回值被保存到model里。
注解 @Cacheable 表明一个方法的返回值应该被缓存,注解 @CacheFlush 声明一个方法是清空缓存的触发器,这两个注解要配合缓存处理器使用。
Spring 允许指定 ModelMap 中哪些属性需要转存到会话中,以便下一个请求还能访问到这些属性。注解 @SessionAttributes 只能标注类,而不能标注方法。
如果希望某个属性编辑器仅作用于特定的控制器 Controller,可以在 Controller 中定义一个被注解 @InitBinder 标注的方法,可以在该方法中向 Controller 注册若干个属性编辑器。
注解 @Required 负责检查一个 Bean 在初始化时其 SET 方法是否被执行,如果 SET 方法没有被调用,则 Spring 在解析时会抛出异常来提醒开发者设置对应的属性。@Required 注解只能标注在 SET 方法上,如果将其标注在非 SET 方法上就会被忽略。
Spring 4.0 中引入了条件化配置特性,提供了更加通用的基于条件的 Bean 创建方法:即使用 @Conditional 注解。@Conditional 根据满足某一特定条件创建一个特定的 Bean。条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这些配置。在 Spring 里可以很方便地编写自定义的条件,只需要实现 Condition 接口并覆盖它的 matches()方法;如下例所示。在下例中,只有当 JdbcTemplateCondition 类的条件成立时才会创建 MyService 这个 Bean。否则,这个 Bean 的声明就会被忽略掉。
//具体条件类,需实现 Condition 接口,并重写 matches(...,...) 方法
public class JdbcTemplateCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata){
try{
context.getc1assLoader().1oadclass(
"org.springframework.jdbc.core.JdbcTemplate");
return true;
} catch (Exception e) {
return false;
}
}
//声明bean时,使用自定义条件类,作为eConditional的参数value
@Conditional(JdbcTemplateCondition.class)
public MyService myService(){...}
}
注解注入是通过注解来实现注入。Spring 中和注入相关的常见注解有 @Autowired、@Resource、@Qualifier、@Service、@Controller、@Repository、@Component 等。其中:
注解 @Autowired 实现自动注入;
注解 @Resource 通过指定名称的方式进行注入;
注解 @Qualifier 和注解 @Autowired 配合使用,通过指定名称的方式进行注入;
注解 @Autowired,@Resource 可以被用来标注字段、构造函数、方法,并进行注入。
注解 @Service、@Controller、@Repository 被用来标注类,Spring 扫描注解标注的类时要生成的 Bean。注解 @Service、@Controller、@Repository 标注的类分别位于服务层、控制层、数据存储层。注解 @Component 是一种泛指,标记被注解的对象是组件。
注解 @EnableAspectJAutoProxy 表示开启 AOP 代理自动配置机制,可以通过设置@EnableAspectJAutoProxy(exposeProxy=true) 表示使用 AOP 框架来暴露该代理对象,这样 aopContext 就能够访问。从注解 @EnableAspectJAutoProxy 的定义可以看出,它引入了一个 AspectJAutoProxyRegister.class 对象,该对象是一个用 @EnableAspectJAutoProxy 注解标注的 AnnotationAwareAspectJAutoProxyCreator。
AnnotationAwareAspectJAutoProxyCreator 能通过调用类 AopConfigUtils 的方法 registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 来注册一个 AOP 代理对象生成器。
注解 @Profiles 提供了一种隔离应用配置的方法,让这些配置只能在特定环境下生效。任何组件或配置类都能被 @Profiles 标记,从而限制它们的加载时机。
注解 @SpringBootApplication 和注解 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解等价。其中,注解 @Configuration 标注在类上,等同于 Spring 的 XML 配置文件中 Bean。注解 @EnablcAutoConfiguration 实现自动配置。注解 @ComponentSca 扫描组件,可自动发现和装配 Bean,并把 Bean 加入到程序上下文。
注解 @RestController 是注解 @Controller 和注解 @ResponscBody 的合集,表示被标注的对象是 REST 风格的 Bean,并且是将方法的返回值直接填入 HTTP 响应正文中返回给用户。
注解 @JsonBackReference 可以用来解决无限递归调用问题。注解 @RepositoryRestResource 配合 spring-boot-starter-data-rest 使用,用于创建 RESTful 入口点。注解 @Import 用来导入其他配置类。注解 @ImportResource 用来加载 XML 配置文件。
注解 @Bean 标注方法等价于 XML 配置中的 Bean。注解 @Value 注入Spring Boot 配置文件 application.properties 中配置的属性值。注解 @Inject 等价于默认的 @Autowired,只是没有 required 属性。
Spring Boot 定义了很多条件,将其运用到了配置类上,这些配置类构成了 Spring Boot 的自动配置。Spring Boot 提供的条件化注解包括 @ConditionalOnBean (配置了某个特定Bean)、@ConditionalOnMissingBean (没有配置特定的 Bean)、@ConditionalOnClass (classPath 目录里有指定的类)、@ConditionalOnMissingClass (classpath 目录里缺少指定的类)、@ConditionalOnExpression (给定的 SpEL表达式计算结果为 true)、@ConditionalOnJava (Java 的版本匹配特定值或者一个范围值)、@ConditionalOnJndi (参数中给定的 JNDI 位置必须存在一个)、@ConditionalOnProperty (指定的配置属性要有一个明确的值)、@ConditionalOnResource (classpath 目录有指定的资源)、@ConditionalOnWebApplication (是一个 Web 应用程序)、@ConditionalOnNotWcbApplication (不是一个 Web 应用程序)。
注解 @Entity 表明被标注的对象是一个实体类,注解 @Table(name=" ") 指出实体对应的表名;这两个注解一般一起使用。但是如果表名和实体类名相同,则 @Table 可以省略。
进行开发项目时,经常会用到将实体类映射到数据库表的操作。有时需要映射的几个实体类有共同的属性,例如编号 ID、创建者、创建时间、备注等。这时,可以把这些属性抽象成一个父类,然后各个实体类继承这个父类。可以使用 @MappedSuperclass 注解标注父类,它不会映射到数据库表,但子类在映射时会自动扫描父类的映射属性,并将这些属性添加到子类对应的数据库表中。使用 @MappedSuperclass 注解后不能再有 @Entity 或 @Table 注解。
SpringData 中提供了很多 DAO 接口,但是依然有可能满足不了日常应用的需要,需要自定义 Repository 实现。注解 @NoRepositoryBean 一般用作父类的 Repository,有这个注解 Spring 不会去实例化该 Repository。
注解 @Column 标识实体类中属性与数据表中字段的对应关系。如果注解 @Column 的字段名与列名相同,则可以省略。@Column 注解一共有 10 个属性,这 10 个属性均为可选属性。常用属性有 name、unique、nullable、table、length、precision、scale 等。其中,name 属性定义了被标注字段在数据库表中所对应字段的名称。unique 属性表示该字段是否为唯一标识,默认值为 false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用 @Table 标记中的 @UniqueConstraint。nullable 属性表示该字段是否可以为 null 值,默认值为 true。table 属性定义了包含当前字段的表名。length 属性表示字段的长度,当字段的类型为 varchar 时,该属性才有效;默认值为 255 个字符。precision 属性和 scale 属性表示精度,当字段类型为 double 时,precision 表示数值的总长度,scale 表示小数点所占的位数。
注解 @Id 用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。@Id 标注也可置于属性的 getter 方法之前。
注解 @GeneratedValue 用于标注主键的生成策略,通过属性 strategy 指定策略。例如,注解 @GeneratedValue(strategy=GenerationType.SEQUENCE) 表示主键生成策略是 scquence,@GeneratedValue(generator =“repair_scq”) 指定 sequence 的名字是 repair_seq。
在 javax.persistcnce.GenerationTypc 中定义了 IDENTITY、AUTO、SEQUENCE 等几种可供选择的策略。其中,IDENTITY 策略表示采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式;SEQUENCE 表示通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySOL 不支持这种方式。默认情况下,JPA 自动选择一个最适合的底层数据库的主键生成策略,例如 SQL Server 对应的默认策略为 identity,MySQL 对应的默认策略为 auto increment。 注解 @SequenceGeneretor(name =“repair_seq”, sequenceName =“seq_repair”,allocationSize=1) 中 name 为 sequence 的名称,以便使用 sequenceName 为数据库的 sequence 名称,两个名称可以一致。
注解 @Transient 表示被标注的属性不是一个到数据库表的字段的映射,对象关系映射 (Objcct Relational Mapping,ORM) 框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为 @Transicnt;否则,ORM 框架默认其注解为 @Basic。注解 @Basic(fetch=FctcbType.LAZY) 可以指定实体属性的加载方式。
注解 @Jsonlgnore 的作用是 JSON 序列化时将 Java Bean 中的一些属性忽略掉,序列化和反序列化都受影响。例如,如果希望返回的 JSON 数据中不包含属性 goodsInfo 和 extendsInfo 快照值;在实体类快照属性上加注解 @JsonIgnore 即可,最后返回的 JSON 数据将不会包含 goodsInfo 和 extendsInfo 两个属性值。
注解 @JoinColumn(name=“loginld”) 表示一张表有指向另一个表的外键。假设 Person 表和 Address 表是一对一的关系,Person 有一个指向 Address 表主键的字段 addressID;可以用注解 @JoinColumn 注解 addressID。@OncToOne、@OneToMany、@ManyToOne、@ManyToMany 对应 Hibernate 配置文件中的一对一、对多、多对一、多对多关系。@ManyToOne 不产生中间表,可以用@Joincolumn(name=" “) 来指定外键的名字。@OneToMany 会产生中间表,可以用 @onetoMany @Joincolumn(name=” ") 避免产生中间表,并且能指定外键的名字。
注解 @ControllerAdvice 包含注解 @Component,可以被扫描到,统一处理异常。
注解 @ExccptionHandler(Exception.class) 用在方法上面表示遇到这个异常就执行所注解的方法。
注解 @PreUpdate 用于为相应的生命周期事件指定回调方法。该注解可以应用于实体类、映射超类或回调监听器类的方法。如果要每次更新实体时都要更新属性,可以使用注解 @PreUpdate 注释。注解 @PreUpdate 不允许更改实体。
注解 @PrePersist 帮助在持久化之前自动填充实体属性。@PrePersist 事件在调用 persist() 方法后立刻发生,此时的数据还没有真正插入数据库。可以用来在使用 JPA 时记录一些与业务无关的字段,如最后更新时间等。生命周期方法注解 (删除没有生命周期事件 @PrePersist 在保存之前被调用,注解 @PostPersist 在保存之后被调用。@PostPersist 事件在数据已经插入数据库后发生。
注解 @PostLoad 在 Entity 被映射之后被调用,注解 @EntityListeners 指定外部生命同期事件实现类。注解 @PostLoad 事件在执行 EntityManager.find() 或 getreference() 方法载入一个实体后、执行 JPA SQL 查询后或 EntityManager.refresh() 方法被调用后执行。
注解 @PreRemove 和注解 @PostRemove 事件的触发由删除实体引起。注解 @PreRemove 事件在实体从数据库删除之前触发。注解 @PostRemove 事件在实体从数据库删除后触发。
注解 @NoArgsConstructor 提供一个无参的构造方法。注解 @AllArgsConstructor 提供一个全参的构造方法。