Java注解(Annotation)总结
- Spring注解
- @Autowired
- @Component、@Repository、@Service、@Controller
- @PostConstruct、@PreDestroy
- Guava注解
- @VisibleForTesting
- Lombok注解
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- @Getter、@Setter
- fastxml注解
- @JsonDeserialize
- @JsonProperty
Spring注解
@Autowired
Spring 2.5引入@Autowired注解,需要导入包org.springframework.beans.factory.annotation.Autowired。它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowired的使用来消除set,get方法。在使用@Autowired之前,我们对一个bean配置起属性时,是这用用的
通过这种方式来,配置比较繁琐,而且代码比较多。
@Autowired按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。
@Autowired(required = false)
private ThreadControl threadControl;
如果我们需要指定要装配bean的名字,可以结合@Qualifier注解一起使用。
@Autowired
@Qualifier(“userJdbcImps”)
private UserRepository userRepository;@Autowired既可以写在字段上,又可以写在setter方法上。如果写在字段上,那么就不需要再写setter方法。
public class TestServiceImpl {
//下面两种@Autowired只要使用一种即可
@Autowired
private UserDao userDao; // 用于字段上@Autowired
public void setUserDao(UserDao userDao) { // 用于属性的方法上
this.userDao = userDao;
}}
在使用@Autowired时,首先在容器中查询对应类型的bean:
• 如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
• 如果查询的结果不止一个,那么@Autowired会根据名称来查找。
• 如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
那么使用@Autowired的原理是什么?
其实在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。
@Component、@Repository、@Service、@Controller
在Annotaion配置注解中用@Component来表示一个通用注释用于说明一个类是一个Spring容器管理的类。即该类已经拉入到Spring的管理中了。而@Controller, @Service, @Repository是@Component的细化,这三个注解比@Component带有更多的语义,它们分别对应了控制层、服务层、持久层的类。
1、@Controller用于标注控制层。
2、@Service用于标注业务层,主要用来进行业务的逻辑处理。
3、@Repository用于标注持久层,也可以说用于标注数据访问组件,即DAO组件。
4、@Component是一个泛化的概念,仅仅表示一个组件 (Bean),当组件不好归类的时候,我们可以使用这个注解进行标注。
Java EE5 引入了@PostConstruct和@PreDestroy这两个作用于Servlet生命周期的注解,实现Bean初始化之前和销毁之前的自定义操作。
以下为@PostConstruct的API使用说明:
PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法必须在将类放入服务之前调用。支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源,用 PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象 ;该方法的返回类型必须为 void;该方法不得抛出已检查异常;应用 PostConstruct 的方法可以是 public、protected、package private 或 private;除了应用程序客户端之外,该方法不能是 static;该方法可以是 final;如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。
@PostConstruct、@PreDestroy
从Java EE5规范开始,Servlet增加了两个影响Servlet生命周期的注解(Annotation):@PostConstruct和@PreDestroy。
@PostConstruct
用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。
此方法必须在将类放入服务之前调用。支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源,用PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。
应用PostConstruct注释的方法必须遵守以下所有标准:
1)该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象;
2)应用PostConstruct的方法可以是 public、protected、package private或private;
3)该方法的返回类型必须为void;
4)除了应用程序客户端之外,该方法不能是static;
5)该方法可以是final;
6)该方法不得抛出已检查异常;
7)如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。
Guava注解
@VisibleForTesting
Guava注解,你可以把这个注解标注到类、方法或者字段上,以便你在测试的时候可以使用他们。
Annotates a program element that exists, or is more widely visible than otherwise necessary, only for use in test code.
测试:
Lombok注解
@Data
@Builder
表示可以通过Builder方式进行初始化
对于类定义:
public class BuilderTest {
@Builder
private static class Builder {
@Builder.Default
private String name = "1232";
}
}
支持通过以下方式进行对象初始化:
Builder builder = Builder.builder().name("buildername").build();
这里,注解@Builder.Default是lombok新增的注解,用来指定属性的默认值。如果不设置该注解,通过Builder.builder().build();初始化的对象,name字段的值为null。
@Builder声明实体,表示可以进行Builder方式初始化;@Value注解表示只公开getter,对所有属性的setter都封闭,即private修饰,所以它不能和@Builder一起用。
@Builder注解存在的问题是,子类的Builder方法不包含父类的属性。
@AllArgsConstructor
生成全参构造函数。
@NoArgsConstructor
@NoArgsConstructor
生成无参构造函数
@Getter、@Setter
可以作用在类上和属性上,放在类上,会对所有的非静态(non-static)属性生成Getter/Setter方法;放在属性上,会对该属性生成Getter/Setter方法。
可以指定Getter/Setter方法的作用域:
lombok生成的getter / setter方法默认作用域将是public,除非你明确指定一个AccessLevel。如下面的例子所示,属性name的作用域是PROTECTED。
@Setter(AccessLevel.PROTECTED)
private String name;
fastxml注解
@JsonDeserialize
@JsonDeserialize(using = ResourceDesrializer.class)
@JsonProperty
此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把service属性序列化为domain:
@JsonProperty(value="domain")
@JsonProperty("domain")
private String service;
使用时引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
@JsonProperty不仅仅是在序列化的时候有用,反序列化的时候也有用,比如有些接口返回的是json字符串,命名又不是标准的驼峰形式,在映射成对象的时候,将类的属性上加上@JsonProperty注解,里面写上返回的json串对应的名字。