等价与XML中配置beans,至关于Ioc容器,它的某个方法头上若是注册了@Bean,就会做为这个Spring容器中的Bean,与xml中配置的bean意思同样。html
@Configuration注解的类必需使用<context:component-scan base-package="XXX"/>
扫描,以下:前端
@Configuration public class MainConfig { //在properties文件里配置 @Value("${wx_appid}") public String appid; protected MainConfig(){} @Bean public WxMpService wxMpService() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; } }
定义一个MainConfig,用@Configuration注解,那MainConfig至关于xml里的beans,里面用@Bean注解的和xml里定义的bean等价,用<context:component-scan base-package=”XXX”/>
扫描该类,最终咱们能够在程序里用@AutoWired或@Resource注解取得用@Bean注解的bean,和用xml先配置bean而后在程序里自动注入同样,目的是减小xml里配置。java
为了简化从properties里取配置,可使用@Value, 能够properties文件中的配置值。git
在dispatcher-servlet.xml里引入properties文件。程序员
<context:property-placeholder location="classpath:test.properties" />
在程序里使用@Value:web
@Value("${wx_appid}") publicString appid;
即便给变量赋了初值也会以配置文件的值为准。ajax
`目前4种注解意思是同样,并无什么区别,区别只是名字不一样。使用方法:正则表达式
<context:component-scan base-package="XXX"/>
扫描被注解的类@Controller public class TestController { }
实现初始化和销毁bean以前进行的操做,只能有一个方法能够用此注释进行注释,方法不能有参数,返回值必需是void,方法须要是非静态的spring
例如:sql
public class TestService { @PostConstruct public void init(){ System.out.println("初始化"); } @PreDestroy public void dostory(){ System.out.println("销毁"); } }
引深一点,Spring 容器中的 Bean 是有生命周期的,Spring 容许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操做,经常使用的设定方式有如下三种:
1.经过实现 InitializingBean/DisposableBean 接口来定制初始化以后/销毁以前的操做方法;
2.经过 <bean>
元素的 init-method/destroy-method属性指定初始化以后 /销毁以前调用的操做方法;
3.在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化以后仍是销毁以前调用
但他们以前并不等价。即便3个方法都用上了,也有前后顺序.
Constructor > @PostConstruct >InitializingBean > init-method
自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将做为首选者,不然将抛出异常
例如:
@Component public class Apple implements Fruit{ @Override public String hello() { return "我是苹果"; } } @Component @Primary public class Pear implements Fruit{ @Override public String hello(String lyrics) { return "梨子"; } } public class FruitService { //Fruit有2个实例子类,由于梨子用@Primary,那么会使用Pear注入 @Autowired private Fruit fruit; public String hello(){ return fruit.hello(); } }
用于指定该Bean是否取消预初始化,用于注解类,延迟初始化
Autowired默认先按byType,若是发现找到多个bean,则,又按照byName方式比对,若是还有多个,则报出异常
//经过此注解完成从spring配置文件中 查找知足Fruit的bean,而后按@Qualifier指定pean @Autowired @Qualifier("pean") public Fruit fruit;
2.若是要容许null 值,能够设置它的required属性为false,如:
@Autowired(required=false) public Fruit fruit;
默认按 byName自动注入,若是找不到再按byType找bean,若是仍是找不到则抛异常,不管按byName仍是byType若是找到多个,则抛异常。
能够手动指定bean,它有2个属性分别是name和type,使用name属性,则使用byName的自动注入,而使用type属性时则使用byType自动注入。
@Resource(name=”bean名字”)
或
@Resource(type=”bean的class”)
这个注解是属于J2EE的,减小了与spring的耦合
java里使用线程用3种方法:
继承Thread,重写run方法
实现Runnable,重写run方法
使用Callable和Future接口建立线程,并能获得返回值
前2种简单,第3种方式特别提示一下,例子以下:
class MyCallable implements Callable<Integer> { private int i = 0; // 与run()方法不一样的是,call()方法具备返回值 @Override public Integer call() { int sum = 0; for (; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); sum += i; } return sum; } }
main方法:
public static void main(String[] args) { // 建立MyCallable对象 Callable<Integer> myCallable = new MyCallable(); // 使用FutureTask来包装MyCallable对象 FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); if (i == 30) { // FutureTask对象做为Thread对象的target建立新的线程 Thread thread = new Thread(ft); // 线程进入到就绪状态 thread.start(); } } System.out.println("主线程for循环执行完毕.."); try { int sum = ft.get(); // 取得新建立的新线程中的call()方法返回的结果 System.out.println("sum = " + sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
而使用@Async可视为第4种方法。基于@Async标注的方法,称之为异步方法,这个注解用于标注某个方法或某个类里面的全部方法都是须要异步处理的。被注解的方法被调用的时候,会在新线程中执行,而调用它的方法会在原来的线程中执行
application.xml形式的配置:
1.第一步配置XML
<!--扫描注解,其中包括@Async --> <context:component-scan base-package="com.test"/> <!-- 支持异步方法执行, 指定一个缺省的executor给@Async使用--> <task:annotation-driven executor="defaultAsyncExecutor" /> <!—配置一个线程执行器--> <task:executor id=" defaultAsyncExecutor "pool-size="100-10000" queue-capacity="10" keep-alive =”5”/>
id:当配置多个executor时,被@Async("id")指定使用;也被做为线程名的前缀。
pool-size:线程池大小
core size:最小的线程数,缺省:1
max size:最大的线程数,缺省:Integer.MAX_VALUE
queue-capacity:当最小的线程数已经被占用满后,新的任务会被放进queue里面,当这个queue的capacity也被占满以后,pool里面会建立新线程处理这个任务,直到总线程数达到了max size,这时系统会拒绝这个任务并抛出TaskRejectedException异常(缺省配置的状况下,能够经过rejection-policy来决定如何处理这种状况)。缺省值为:Integer.MAX_VALUE
keep-alive:超过core size的那些线程,任务完成后,再通过这个时长(秒)会被结束掉
rejection-policy:当pool已经达到max size的时候,如何处理新任务
ABORT(缺省):抛出TaskRejectedException异常,而后不执行DISCARD:不执行,也不抛出异常
DISCARD_OLDEST:丢弃queue中最旧的那个任务
CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
2.第二步在类或方法上添加@Async,当调用该方法时,则该方法便是用异常执行的方法单独开个新线程执行
@Async(“能够指定执行器id,也能够不指定”) public static void testAsyncVoid (){ try { //让程序暂停100秒,至关于执行一个很耗时的任务 System.out.println(“异常执行打印字符串”); Thread.sleep(100000); } catch (InterruptedException e) { e.printStackTrace(); } }
当在外部调用testAsync方法时即在新线程中执行,由上面<task: annotation-driven/>执行器去维护线程。
总结:先用context:component-scan去扫描注解,让spring能识别到@Async注解,而后task:annotation-driven去驱动@Async注解,并能够指定默认的线程执行器executor。那么当用@Async注解的方法或类获得调用时,线程执行器会建立新的线程去执行。
上面方法是无返回值的状况,还有异常方法有返回值的例子
@Async public Future<String> testAsyncReturn () { System.out.println("Execute method asynchronously - " + Thread.currentThread().getName()); try { Thread.sleep(5000); return new AsyncResult<String>("hello world !!!!"); } catch (InterruptedException e) { // } return null; }
返回的数据类型为Future类型,接口实现类是AsyncResult
调用方法以下:
public void test(){ Future<String> future = cc.testAsyncReturn(); while (true) { ///这里使用了循环判断,等待获取结果信息 if (future.isDone()) { //判断是否执行完毕 System.out.println("Result from asynchronous process - " + future.get()); break; } System.out.println("Continue doing something else. "); Thread.sleep(1000); } }
经过不停的检查Future的状态来获取当前的异步方法是否执行完毕
编程的方式使用@Async:
@Configuration @EnableAsync public class SpringConfig { private int corePoolSize = 10; private int maxPoolSize = 200; private int queueCapacity = 10; private String ThreadNamePrefix = "MyLogExecutor-"; @Bean public Executor logExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setThreadNamePrefix(ThreadNamePrefix); // rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
@Named和Spring的@Component功能相同。@Named能够有值,若是没有值生成的Bean名称默认和类名相同。好比
@Named public class Person
或
@Named("cc") public class Person
使用@Inject须要引用javax.inject.jar,它与Spring没有关系,是jsr330规范
与@Autowired有互换性
只要在类上加上这个注解,就能够实现一个单例类,不须要本身手动编写单例实现类
@Valid
网上一大片使用@Valid失效不能用的状况。为何呢?
@Valid必需使用在以@RequestBody接收参数的状况下。
使用ajax以POST方式提示数据,禁止用Fiddler以及浏览器直接访问的方式测试接口
用
@Valid是应用在javabean上的校验
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jaxb-annotations</artifactId> <version>2.5.3</version>
这些jar包是须要的。@Valid是使用hibernate validation的时候使用,可参数下面介绍的@RequestBody
6.@Valid下后面紧跟BindingResult result,验证结果保存在result
例如:
@RequestMapping("/test") public String testValid(@Valid User user, BindingResult result){ if (result.hasErrors()){ List<ObjectError> errorList = result.getAllErrors(); for(ObjectError error : errorList){ System.out.println(error.getDefaultMessage()); } } return "test"; }
在入参User上添加了@Valid作校验,在User类里属性上实行实际的特定校验。
例如在User的name属性上加
@NotBlank private String name;
所有参数校验以下:
空检查
注解 | 含义 |
---|---|
@Null | 验证对象是否为null |
@NotNull | 验证对象是否不为null, 没法查检长度为0的字符串 |
@NotBlank | 检查约束字符串是否是Null还有被Trim的长度是否大于0,只对字符串,且会去掉先后空格 |
@NotEmpty | 检查约束元素是否为NULL或者是EMPTY |
Booelan检查
注解 | 含义 |
---|---|
@AssertTrue | 验证 Boolean 对象是否为 true |
@AssertFalse | 验证 Boolean 对象是否为 false |
长度检查
注解 | 含义 |
---|---|
@Size(min=, max=) | 验证对象(Array,Collection,Map,String)长度是否在给定的范围以内 |
@AssertFalse | 验证注解的元素值长度在min和max区间内 |
日期检查
注解 | 含义 |
---|---|
@Past | 验证 Date 和 Calendar 对象是否在当前时间以前 |
@Future | 验证 Date 和 Calendar 对象是否在当前时间以后 |
@Pattern | 验证 String 对象是否符合正则表达式的规则 |
数值检查
建议使用在Stirng,Integer类型,不建议使用在int类型上,由于表单值为“”时没法转换为int,但能够转换为Stirng为"",Integer为null
注解 | 含义 |
---|---|
@Min(value=””) | 验证 Number 和 String 对象是否大等于指定的值 |
@Max(value=””) | 验证 Number 和 String 对象是否小等于指定的值 |
@DecimalMax(value=值) | 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个经过BigDecimal定义的最大值的字符串表示.小数存在精度 |
@DecimalMin(value=值) | 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个经过BigDecimal定义的最小值的字符串表示.小数存在精度 |
@Digits | 验证 Number 和 String 的构成是否合法 |
@Digits(integer=,fraction=) | 验证字符串是不是符合指定格式的数字,interger指定整数精度,fraction指定小数精度 |
@Range(min=, max=) | 检查数字是否介于min和max之间 |
@Valid | 递归的对关联对象进行校验, 若是关联对象是个集合或者数组,那么对其中的元素进行递归校验,若是是一个map,则对其中的值部分进行校验.(是否进行递归验证) |
@CreditCardNumber | 信用卡验证 |
验证是不是邮件地址,若是为null,不进行验证,算经过验证 | |
@ScriptAssert(lang=,script=, alias=) | |
@URL(protocol=,host=,port=,regexp=, flags=) |
@Range(min=10000,max=50000,message="range.bean.wage") private BigDecimal wage;
@Validated
@Valid是对javabean的校验,若是想对使用@RequestParam方式接收参数方式校验使用@Validated
使用@Validated的步骤:
第一步:定义全局异常,让该全局异常处理器能处理因此验证失败的状况,并返回给前台失败提示数据。以下,该类不用在任何xml里配置
import javax.validation.ValidationException; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice @Component public class GlobalExceptionHandler { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public String handle(ValidationException exception) { System.out.println("bad request, " + exception.getMessage()); return "bad request, " + exception.getMessage(); } }
第二步。在XXController.java头上添加@Validated,而后在@RequestParam后台使用上面介绍的验证注解,好比@NotBlank,@Rank.
以下:
@Controller @RequestMapping("/test") @Validated public class TestController extends BaseController { @RequestMapping(value = "testValidated", method = RequestMethod.GET) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public Object testValidated( @RequestParam(value = "pk", required = true) @Size(min = 1, max = 3) String pk, @RequestParam(value = "age", required = false) @Range(min = 1, max = 3) String age) { try { return "pk:" + pk + ",age=" + age; } catch (Throwable t) { return buildFailure("消息列表查询失败"); } } }
当入非法参数是,会被全局处理器拦截到,(Spring切面编程方式),若是参数非法即刻给前台返回错误数据。
测试:http://127.0.0.1:8080/TestValidate/test/testValidated?pk=2&age=12
返回:
注意:
@Validated与@RequestBody结合使用时,在接口方法里要增长@Valid。
例如:
public Object edit(@Valid @RequestBody AddrRo addrRo) {.....}
@RequestBody(required=true):有个默认属性required,默认是true,当body里没内容时抛异常。
application/x-www-form-urlencoded:窗体数据被编码为名称/值对,这是标准的编码格式,这是默认的方式。
multipart/form-data:窗体数据被编码为一条消息,页上的每一个控件对应消息中的一个部分,二进制数据传输方式,主要用于上传文件。
注意:
必需使用POST方式提交参数,须要使用ajax方式请求,用Fiddler去模拟post请求不能。
引用jar包:Spring相关jar包。
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency>
dispatchServlet-mvc.xml配置
第一种,直接配置MappingJackson2HttpMessageCoverter:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> </bean> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> </bean> </property> </bean>
第二种:<mvc:annotation-driven/>
就不用配置上面bean,默认会配好
Ajax请求:
function testRequestBody() { var o = {"status":9}; jQuery.ajax({ type: "POST", url: "http://127.0.0.1:8080/TestValidate/test/testValid", xhrFields:{ withCredentials:true }, data: JSON.stringify(o), contentType: "application/json", dataType: "json", async: false, success:function (data) { console.log(data); }, error: function(res) { console.log(res); } }); }
后台XXXcontroller.java:
@RequestMapping(value="/ testValid ",method=RequestMethod.POST) @ResponseBody public Object setOrderInfo(@RequestBody InfoVO infoVO,HttpServletRequest request, HttpServletResponse response){ InfoVO cVo = getInfoVo(infoVO); return "success"; }
开发时,不是报415,就是400错误,头都大了。仍是细节没作到位,注意下面几个要点:
Content-Type必需是application/json
须要jackson-databind.jar
<mvc:annotation-driven/>
要配置或直接配置beanXXXController.jar在post方式接收数据
最最重要的,使用ajax以post方式请求。不能用Fiddler模拟,否则会出错
Cross-Origin ResourceSharing(跨域资源共享)的简写
做用是解决跨域访问的问题,在Spring4.2以上的版本可直接使用。在类上或方法上添加该注解
例如:
@CrossOrigin public class TestController extends BaseController { }
若是失效则可能方法没解决是GET仍是POST方式,指定便可解决问题
做用是提取和解析请求中的参数。
@RequestParam支持类型转换,类型转换目前支持全部的基本Java类型
@RequestParam([value="number"], [required=false]) String number
将请求中参数为number映射到方法的number上,required=false表示该参数不是必需的,请求上可带可不带。
@PathVariable:处理requet uri部分,当使用@RequestMapping URI template 样式映射时, 即someUrl/{paramId}, 这时的paramId可经过 @Pathvariable注解绑定它传过来的值到方法的参数上
例如:
@Controller @RequestMapping("/owners/{a}") public class RelativePathUriTemplateController { @RequestMapping("/pets/{b}") public void findPet(@PathVariable("a") String a,@PathVariable String b, Model model) { // implementation omitted } }
@RequestHeader,@CookieValue: 处理request header部分的注解
将头部信息绑定到方法参数上:
@RequestMapping("/test") public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive")long keepAlive) { //... }
将cookie里JSESSIONID绑定到方法参数上:
@RequestMapping("/test") public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) { //... }
@RequestParam, @RequestBody
@SessionAttributes,@ModelAttribute:处理attribute类型注解
配置bean的做用域
@Controller @RequestMapping("/test") @Scope("prototype") public class TestController { }
默认是单例模式,即@Scope("singleton")
域 | 说明 |
---|---|
singleton | 单例,容器里只有一个实例对象 |
prototype | 多对象,每一次请求都会产生一个新的bean实例,Spring不没法对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,由程序员负责销毁该对象,无论何种做用域,容器都会调用全部对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用 |
request | 每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效 |
session | 同一个session共享一个bean,不一样的session使用不一样的bean |
web.xml增长以下配置:
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> session:该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效。也要在web.xml配置以下代码: <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> global session:做用不大,可不用管他。
@ResponseStatus用于修饰一个类或者一个方法,修饰一个类的时候,通常修饰的是一个异常类,当处理器的方法被调用时,@ResponseStatus指定的code和reason会被返回给前端。value属性是http状态码,好比404,500等。reason是错误信息
当修改类或方法时,只要该类获得调用,那么value和reason都会被添加到response里
例如:
@ResponseStatus(value=HttpStatus.FORBIDDEN, reason="出现了错误") public class UserException extends RuntimeException{ }
当某处抛出UserException时,则会把value和reason返回给前端
@RequestMapping("/testResponseStatus") public String testResponseStatus(int i){ if(i==0) throw new UserNotMatchException(); return "hello"; }
修改方法:
@ControllerAdvice @Component public class GlobalExceptionHandler { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @ExceptionHandler @ResponseBody @ResponseStatus(value=HttpStatus.BAD_REQUEST,reason="哈哈") public String handle(ValidationException exception) { System.out.println("bad request, " + exception.getMessage()); return "bad request, " + exception.getMessage(); } }
结果以下:
正如上面所说,该方法获得调用,不管是否抛异常,都会把value和reason添加到response里。
总结:@ResponseStatus是为了在方法或类获得调用时将指定的code和reason添加到response里返前端,就像服务器常给咱们报的404错误同样,咱们能够本身指定高逼格错误提示。
@RestController = @Controller + @ResponseBody。
是2个注解的合并效果,即指定了该controller是组件,又指定方法返回的是String或json类型数据,不会解决成jsp页面,注定不够灵活,若是一个Controller即有SpringMVC返回视图的方法,又有返回json数据的方法即便用@RestController太死板。
灵活的做法是:定义controller的时候,直接使用@Controller,若是须要返回json能够直接在方法中添加@ResponseBody
官方解释是:It is typically used todefine@ExceptionHandler, @InitBinder, and@ModelAttribute methods that apply to all@RequestMapping methods.
意思是:即把@ControllerAdvice注解内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到全部的 @RequestMapping注解的方法。很是简单,不过只有当使用@ExceptionHandler最有用,另外两个用处不大。
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(SQLException.class) @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR,reason=”sql查询错误”) @ResponseBody public ExceptionResponse handleSQLException(HttpServletRequest request, Exception ex) { String message = ex.getMessage(); return ExceptionResponse.create(HttpStatus.INTERNAL_SERVER_ERROR.value(), message); } }
即表示让Spring捕获到全部抛出的SQLException异常,并交由这个被注解的handleSQLException方法处理,同时使用@ResponseStatus指定了code和reason写到response上,返回给前端
元注解是指注解的注解,好比咱们看到的ControllerAdvice注解定义以下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface ControllerAdvice { }
@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时没法得到
@Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时能够经过反射获取到
@Target:定义注解的做用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) //包
由以上的源码能够知道,他的elementType 能够有多个,一个注解能够为类的,方法的,字段的等等
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类能够继承父类中的该注解
好比@Valid注解定义是:
表示该注解只能用在方法,属性,构造函数及方法参数上。该注意会被编译到class里可经过反射获得。
处理映射请求的注解。用于类上,表示类中的全部响应请求的方法都是以该地址做为父路径,有6个属性。
1.value, method:
value:指定请求的实际地址,指定的地址能够是URI Template 模式;
method:指定请求的method类型, GET、POST、PUT、DELETE等;
好比:
@RequestMapping(value = "/testValid", method = RequestMethod.POST) @ResponseBody public Object testValid(@RequestBody @Valid Test test,BindingResult result, HttpServletRequest request, HttpServletResponse response) { }
value的uri值为如下三类:
2.consumes,produces:
consumes: 指定处理请求的提交内容类型(Content-Type),例如@RequestMapping(value = "/test", consumes="application/json")处理application/json内容类型
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3.params, headers
params: 指定request中必须包含某些参数值是,才让该方法处理。
例如:
@RequestMapping(value = "/test", method = RequestMethod.GET, params="name=chenyuan") public void findOrd(String name) { // implementation omitted }
仅处理请求中包含了名为“name”,值为“chenyuan”的请求.
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@RequestMapping(value = "/test", method = RequestMethod.GET, headers="Referer=www.baidu.com") public void findOrd(String name) { // implementation omitted }
仅处理request的header中包含了指定“Refer”请求头和对应值为“www.baidu.com”的请求
另赠spring提供的注解:
@GetMapping(value = "page")等价于@RequestMapping(value = "page", method = RequestMethod.GET)
@PostMapping(value = "page")等价于@RequestMapping(value = "page", method = RequestMethod.POST)