Spring框架中的注解

@RestController

@RestController结合了@Controller@ResponseBody方便实现RESTful服务的注解

当返回的是对象时, 会以JSON数据进行传输


@Controller

用于标注控制层组件


@RequestMapping

用于处理请求地址映射的注解, 可用于类或方法上

当作用于类上时, 表示类中的所有响应请求的方法以该注解上的地址作为父级路径

  • value

    @RequestMapping(value="/")(显示声明)@RequestMapping("/")(隐式声明)

    指定请求的实际路由, 可分为以下三类:

    1. 普通的URI

      value=”/demo”

    2. 含有某变量的URI

      1
      value="/get/{year}/{month}/{day}"
    3. 含有正则表达式的URI

      1
      value="/spring-web/{symbolicName: [a-z-]+}-{version: \d.\d.\d}.{extension: \\.[a-z]}"
  • method

    @RequestMapping(method="POST")@RequestMapping(method=RequestMethod.GET)

    指定请求的method类型

  • consumes

    @RequestMapping(consumes="text/html")

    指定处理请求的提交内容类型(Content-Type), 例如:application/json, text/html

  • produces

    @RequestMapping(produces="text/html")

    指定返回的内容类型, 当且仅当request请求头里面Accept类型中包含该指定类型才返回

  • params

    @RequestMapping(params={"username=kobe", "password=123456"})

    指定request中必须包含某些指定的参数值, 才会正常处理该响应

  • headers

    @RequestMapping(headers={})

    指定request中必须包含某些指定的header值 , 才会正常处理该响应

常用的辅助注解:

@RequestParam

针对于提交的表格信息进行直接获取, 也可以通过HttpServletRequest对表格信息进行间接获取(request.getParameter(“name”))

1
2
3
4
<!-- 前端代码 -->
<form action="/getForm">
<input name="name" value="jianpeng"/>
</form>
1
2
3
4
5
// 后端代码
@RequestMapping("/getForm")
public void getForm(@RequestForm String name) {
...
}

@RequestBody

接收JSON对象的字符串形式, 而非JSON对象

1
2
3
4
@RequestMapping("/getJson")
public void getJson(@RequestBody List<User> users) {
...
}

@PathVariable

当@RequestMapping(“/{day}”)中含有动态变量时, 可在响应方法的参数列表中声明该形式参数为路由中的参数

1
2
3
4
@RequestMapping("/{day}")
public void getDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day) {
...
}

@ResponseBody

表示处理函数直接将函数的返回值传回到浏览器端显示


@Resource@Autowired

都可用于装配bean, 即可写在字段上, 也可写在setter方法上.

1
2
3
4
5
6
7
8
9
10
11
12
/*
* 通过在变量上进行注解优先级大于在setter方法上进行注解
* 因为可以在不暴露setter方法的情况下, 使代码更加紧凑, 提高封装性
*/
@Resource
private String name;

// 通过@Resource注解注入与setter形参上变量名称相同的bean
@Resource
public void setName(String name) {
this.name = name;
}

@Autowired

默认按类型装配(该注解属于Spring框架中), 默认情况下必须要求依赖对象存在, 如果允许null值, 则可以设置它的required属性为false, 如: @Autowired(required=”false”)

@Autowired也可指定name来装配bean, 但必须与@Qualifier一起搭配使用

1
2
@Autowired @Qualifier("baseDao")
private BaseDao baseDao;

@Resource

默认按变量名进行装配(该注解属于JDK中), 名称可以通过name制定, 如: @Resource(name=”baseName”), 但如果一旦按照name制定, 则只会通过name进行装配工作

1
2
@Resource
private BaseDao baseDao;

虽然两者作用的同一地方的不同部分, 但实际开发工作中的作用是一样的, 最好进行统一即可


@Service

用于标注业务(服务)层组件


@Repository

用于标注持久层, 即数据访问层(DAO)组件


@Component

泛指组件, 在spring2.5前@Service、@Controller和@Repository三种不同层的注解统称为@Component

在含义不清时可以暂时给一个应用层进行分类时可使用


@EnableWebMvc

完全控制Spring MVC, 你可以在@Configuration注解的配置类上增加@EnableWebMvc, 增加该注解以后WebMvcAutoConfiguration中配置就不会生效, 你需要自己来配置需要的每一项**. 这种情况下的配置方法建议参考WebMvcAutoConfiguration


@Bean

用于该类/方法/变量可注册为Bean并交由Spring管理(可通过name指定需要管理的Bean的名字)


@Value

用于从配置文件中获取值

1
2
@Value({spring.database.username})
private String username = 'root';

@Value无法获取值且被注解的变量中存在赋值时, 则使用设计者直接主动赋予的变量值作为默认值


@Import

用于导入不同包下java类文件, 并交由Spring管理其中的已注册的Bean


@ImportResource

用于引入基于XML的配置文件, 同理向上

  • locations

    从外部导入文件的路径, 有两种形式:

    • classpath - 从工程/resource下导入

      1
      locations={"classpath:application-bean1.xml", "classpath:application-bean2.xml"}
    • file - 从系统中以绝对路径的形式导入

      1
      locations={"file:d:/demo/application-bean3.xml"}

@EnableAutoConfiguration

用于表明Spring Boot可以根据添加的jar依赖猜测你想如何配置Spring

作用于@Configuration下的常见的@EnableXX注解

@EnableAspectJAutoProxy 开启对AspectJ自动代理的支持
@EnableAsync 开启异步方法的支持
@EnableScheduling 开启计划任务的支持
@EnableWebMvc 开启Web MVC的配置支持.
@EnableConfigurationProperties开启对@ConfigurationProperties注解配置Bean的支持.
@EnableJpaRepositories开启对Spring Data JPA Repository的支持.
@EnableTransactionManagement 开启注解式事务的支持.
@EnableCaching开启注解式的缓存支持


@ComponentScan

作用于配置类上, 用于扫描主程序位于的包以及子包下的所有组件(@Component/@Controller/@Service/@Repository)


Spring集成了基于JSR-303的Bean Validation框架, 支持设计者进行数据校验工作

JSR-303是一个数据验证的规范

Bean Validation是一个通过配置注解来验证参数的框架, 它包含两部分Bean Validation API和Hibernate Validator.

  • Bean Validation API是Java定义的一个验证参数的规范.
  • Hibernate Validator是Bean Validation API的一个实现扩展.

Bean Validation 中的 constraint

表 1. Bean Validation 中内置的 constraint
Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字, 其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字, 其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字, 其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字, 其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字, 其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
表 2. Hibernate Validator 附加的 constraint
Constraint 详细信息
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内

@Valid - 注释要求要对该参数/变量通过校验器进行校验**

Spring一旦发现@Valid注解, 就会根据被注解类中的注解规则进行数据校验, 所以如果当数据不符合校验规则, 会出现如下错误提示:

1
Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as a fallback.Fri Aug 21 10:09:54 CST 2015There was an unexpected error (type=Bad Request, status=400).Validation failed for object='post'. Error count: 2

但为了让用户体验更加良好, 我们需要将自定义的错误页面呈现出来, 以下为有错误时的处理代码:

1
2
3
4
5
6
7
8
@RequestMapping(value = "/", method = RequestMethod.POST)
public String create(@Valid Demo demo, BindingResult result) {
if (result.hasErrors()) {
return "error";
}

return "demo";
}

@ControllerAdvice

可视为一种增强版拦截器. 能把@ControllerAdvice注解内部所使用的@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有(或特定)的 @RequestMapping注解的方法.

1
2
3
4
5
6
7
8
9
10
@ControllerAdvice
public class GlobalDefaultExceptionHandler {

// 可返回任意数据/页面, 与Controller同样用法
@ExceptionHanlder(value=Exception.class)
public voud defaultErrorHandler(HttpServletRequest req, Exception e) {
e.printStackTrace();
System.out.println("GlobalDefaultExceptionHandler.defaultErrorHandler() raise");
}
}
  • 默认情况 - 全局拦截

    1
    @ControllerAdvice
  • 仅在内部添加字符串(不声明属性名) - 作用于指定的包

    1
    @ControllerAdvice("com.example.contoller")
  • assignableTypes - 作用于指定的类

    1
    @ControllerAdvice(assignableTypes={ControllerA.class, ControllerB.class})
  • annotations - 作用于指定的注解

    1
    @ControllerAdvice(annotations=RestController.class)

@ManyToOne 与 @OneToMany

@ManyToOne 从字面意思可知为 多对一, @OneToMany 为 一对多.

以上解释好比于书单与图书的关系, 一张书单可以对应多本不同图书, 一本图书可以对应多张书单. JPA通过其中的映射关系将获取的值注入到被注释的变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Entity
public class Order {
@Id
@GeneratedValue
private long id;

/*
* @OneToMany: 指明Order与OrderItem关联关系为一对多关系
*
* mappedBy: 定义类之间的双向关系. 如果类之间是单向关系, 不需要提供定义, 如果类和类之间形成双向关系, 我们就需要使用这个属性进行定义, 否则可能引起数据一致性的问题.
*
*
* cascade: CascadeType[]类型. 该属性定义类和类之间的级联关系. 定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,
* 而且这种关系是递归调用的. 举个例子:Order 和OrderItem有级联关系, 那么删除Order 时将同时删除它所对应的OrderItem对象.
* 而如果OrderItem还和其他的对象之间有级联关系, 那么这样的操作会一直递归执行下去. cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个.
* 还有一个选择是使用CascadeType.ALL, 表示选择全部四项.
*
*
* fatch: 可选择项包括:FetchType.EAGER 和FetchType.LAZY. 前者表示关系类(本例是OrderItem类)在主类(本例是Order类)加载的时候同时加载; 后者表示关系类在被访问时才加载,默认值是FetchType.LAZY.
*
*/
@OneToMany(mappedBy="order", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@Order(value="id ASC")
private List<OrderItem> OrderItems;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Entity
public class OrderItem {
@Id
@GeneratedValue
private int id;

/*
* @ManyToOne指明OrderItem和Order之间为多对一关系, 多个OrderItem实例关联的都是同一个Order对象.
* 其中的属性和@OneToMany基本一样, 但@ManyToOne注释的fetch属性默认值是FetchType.EAGER.
*
* optional 属性是定义该关联类对是否必须存在.
* 值为false时, 关联类双方都必须存在, 如果关系被维护端不存在, 查询的结果为null.
* 值为true 时, 关系被维护端可以不存在, 查询的结果仍然会返回关系维护端, 在关系维护端中指向关系被维护端的属性为null.
* optional 属性的默认值是true. 举个例:某项订单(Order)中没有订单项(OrderItem), 如果optional 属性设置为false, 获取该项订单(Order)时, 得到的结果为null, 如果optional 属性设置为true, 仍然可以获取该项订单, 但订单中指向订单项的属性为null.
* 实际上在解释Order与OrderItem的关系成SQL时, optional 属性指定了他们的联接关系optional=false联接关系为inner join,
* optional=true联接关系为left join.
*
*
* @JoinColumn:指明了被维护端(OrderItem)的外键字段为order_id, 它和维护端的主键(order_id)连接, unique=true指明order_id列的值不可重复.
*/
@ManyToOne(cascade=CascadeType.REFRESH, optional=false)
@JoinColumn(name="order_id", referencedColumnName="order_id")
private Order order;
}

@Transactional

表明指定类(通常为Service类)下的所有方法或表明某些指定的方法需要进行事务管理

1
2
3
4
5
@Service
@Transactional
public class DemoServiceImpl implements DemoService {
...
}

Transactional注解中常用参数说明

参数名称 功能描述
readOnly 该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
rollbackFor 该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName 该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称:@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
noRollbackFor 该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName 该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
propagation 该属性用于设置事务的传播行为, 例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
isolation 该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
timeout 该属性用于设置事务的超时秒数,默认值为-1表示永不超时
  • propagation
    • @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
    • @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事
    • @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
    • @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
    • @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
    • @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

@Async - 异步


@Cacheable 创建

@CachePut 更新

@CacheEvict 删除


@Scheduled


@NamedQuery


@Modifying

@Query


@EnableEurekaClient

@EnableDiscoveryClient


@Profile


参考文章:

[1] http://www.importnew.com/18561.html

[2] https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/

[3] https://course.tianmaying.com/web-development+form-validation#0

[4] http://blog.longjiazuo.com/archives/1366

[5] http://jinnianshilongnian.iteye.com/blog/1866350

[6] http://lym6520.iteye.com/blog/312125

[7] http://www.cnblogs.com/caoyc/p/5632963.html