1.@Controller
@Controller用于标记控制层(Controller层)
2.@Service
@Service用于标记服务层(Service层)
3.@Repository
@Repository用于标记访问层(DAO层)
4.@Component
@Component用于标记实体类层(Entity层),使用该注解,相当于将实体类实例化到Spring容器
5.@RequestMapping
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径
@RequestMapping注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String[ ] | 否 | 用于将指定请求的实际地址映射到方法上(默认属性) |
name | String | 否 | 给映射地址指定一个别名(就是一个所谓的类注释,和注释没啥区别,显得更加友好罢了) |
method | RequestMethod[ ] | 否 | 映射指定请求的方法类型,常用的是GET,POST |
consumes | String[ ] | 否 | 指定处理请求的提交内容类型(Content-Type),例如:application/json、text/html等 |
produces | String[ ] | 否 | 指定返回的内容类型,返回的内容类型必须是request请求头(Accept)中所包含的类型 |
params | String[ ] | 否 | 指定请求中,必须包含某些参数值时,才让该方法处理 |
headers | String[ ] | 否 | 指定请求中必须包含某些指定的header值,才能让该请求方法处理 |
path | String[ ] | 否 | 和value属性差不多,都是用来作为映射使用的 |
详细使用,请查看博文:@RequestMapping各个属性的使用
6.@ResponseBody
@responseBody注解的作用是将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到Response对象的body区,通常用来返回JSON数据或者是XML数据。
需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,它的效果等同于通过response对象输出指定格式的数据。
7.@RequestParam
@RequestParam注解,用于将指定的请求参数赋值给方法中的形参
@RequestParam注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String | 否 | 指定请求头绑定的名称(默认属性) |
name | String | 否 | value属性的别名 |
required | boolean | 否 | 指定参数是否必须绑定(默认为true) |
defaultValue | String | 否 | 如果没有传递参数,则是用默认值 |
@RequestMapping("test")
public void test(@RequestParam String id,@RequestParam String name){
System.out.println(id);
System.out.println(name);
}
①@RequestParam,源码中name的别名是value,value的别名是name。所以说name和value两个属性基本是等价的
②由于value属性是@RequestParam注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的【@RequestParam(value="id"),@RequestParam("id")】
// 前端发送请求http://localhost:8080/xxx/test?id=1&name=lzb
// 第一种情况:
public void test(@RequestParam String id,@RequestParam String name){
//默认情况,即请求参数和形参进行匹配。此处id,即为请求传过来的id参数,name也一样
System.out.println(id); ---->1
System.out.println(name);--->lzb
}
// 第二种情况:
public void test(@RequestParam("id") String id,@RequestParam("name") String name){
//由于value属性是@RequestParam注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的
//@RequestParam(value="id")
//@RequestParam("id")
System.out.println(id); ---->lzb
System.out.println(name);--->1
}
// 第三种情况:
public void test(@RequestParam(name="name") String id,@RequestParam(name="id") String name){
//此处形参id,指定接受的是请求传过来的name属性,形参name,指定接收的是请求传过来的id属性
System.out.println(id); ---->lzb
System.out.println(name);--->1
}
// 第四种情况:
public void test(@RequestParam(defaultValue="88") String id,@RequestParam(defaultValue="Mary") String name){
//设置默认参数后,请求连接不带参数的话,则形参为默认参数
System.out.println(id); ---->88
System.out.println(name);--->Mary
}
// 第五种情况:
public void test(@RequestParam(required=false) String id,@RequestParam(defaultValue="Mary") String name){
//设置required=false后,则说明id参数不是必须绑定,发送http://localhost/test请求后,id值就是null了
System.out.println(id); ---->null
System.out.println(name);--->Mary
}
8.@PathVariable
@PathVariable注解,可以非常方便的获取请求URL参数中的动态参数,然后直接赋值给请求方法的形参
@RequestMapping("test/{userId}")
public void test(@PathVariable String userId){
System.out.println(userId);
}
发送请求URL:http://localhost:8080/test/1001,由@PathVariable 注解的String userId参数会自动获取到URL参数中的动态参数1001,并赋值给形参userId,此处userId即为1001
@RequestMapping("test/{id}")
public void test(@PathVariable(value = "id") String userId){
System.out.println(userId);
}
如果形参名称和@RequestMapping请求的动态参数名称不一样,则@PathVariable需要加上value属性来设置。从而保证动态参数能够顺利赋值给形参userId
9.@CookieValue
@CookieValue注解,能够将请求的Cookie数据映射到请求处理方法的形参上
@RequestMapping("test")
public void test(@CookieValue String JSESSIONID){
System.out.println(JSESSIONID);
}
如果要先在此处获取到JSESSIONID,前提是得在调用该请求之前,设置name为JSESSIONID的cookie信息。然后调用该请求的时候,形参JSESSIONID就能够获取到该Cookie值
@RequestMapping("test")
public void test(@CookieValue(value = "JSESSIONID") String cookie){
System.out.println(cookie);
}
如果Cookie值的name值和形参中的变量不同(假设Cookie中name值为JSESSIONID,形参值为cookie),则需要使用@CookieValue中的value参数了。需要该value的值与cookie的name值一致,形参才能获取到值。如上所示
@CookieValue注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String | 否 | 指定请求头绑定的名称(默认属性) |
name | String | 否 | value属性的别名 |
required | boolean | 否 | 指定参数是否必须绑定(默认为true) |
defaultValue | String | 否 | 如果没有传递参数,则是用默认值 |
10.@RequestHeader
@RequestHeader注释,用于将请求的头信息数据,映射到请求方法的形参上
@RequestMapping("test")
public void test(@RequestHeader("User-Agent") String userAgent,@RequestHeader(value = "Accept") String[] accepts){
System.out.println(userAgent);
System.out.println(accepts);
}
@RequestHeader的使用,和@CookieValue的使用都差不多,支持的属性也都一致,故不作详细解释
@RequestHeader注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String | 否 | 指定请求头绑定的名称(默认属性) |
name | String | 否 | value属性的别名 |
required | boolean | 否 | 指定参数是否必须绑定(默认为true) |
defaultValue | String | 否 | 如果没有传递参数,则是用默认值 |
11.@SessionAttributes
转存到HttpSession对象当中
@SessionAttributes只能声明在类上,而不能声明在方法上
@SessionAttribures注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String[ ] | 否 | Model中属性的名称,即存储在HttpSession当中的属性的名称(默认属性) |
names | String[ ] | 否 | value属性的别名 |
types | Class<?> [ ] | 否 | 指定参数的类型 |
由于value属性是@SessionAttributes注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的【@SessionAttributes(value={"user","age","address"}),@RequestParam({"user","age","address"})】
@Controller
@RequestMapping("user")
@SessionAttributes(value = {"user","age","address"},types = {String.class,Int.class,String.class})
public class UserController {
@RequestMapping("getUser")
@ResponseBody
public ModelAndView getUser(HttpSession session){
ModelAndView view = new ModelAndView();
view.setViewName("getUser");
view.addObject("user","Mary");
view.addObject("age",19);
view.addObject("address","北京市");
String user = (String)session.getAttribute("user");
System.out.println(user);
return view;
}
}
此处,可以看到@SessionAttributes注解同时将getUser( ) 方法中的"user","age","address"三个同时放入到了HttpSession中,所以通过session.getAttribute("user")即可获取到相关的数据
getUser( )方法结束后,会直接跳转到名称为getUser的页面,在此页面也可以直接通过EL表达式来获取到session数据
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>getUser</title>
</head>
<body>
${sessionScope.user} ----Mary
${sessionScope.age} -----11
${sessionScope.address} ----北京市
</body>
</html>
12.@SessionAttribute
@SessionAttribute注解,能够非常方便的将Session数据映射到请求处理方法的形参上
@SessionAttribure注解支持的属性
属性 | 类型 | 是否必要 | 说明 |
value | String | 否 | Model中属性的名称,即存储在HttpSession当中的属性的名称(默认属性) |
names | String | 否 | value属性的别名 |
required | Class<?> | 否 | 指定参数是否必须绑定(默认为true) |
@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute String user){
System.out.println(user);
}
形参和session中的name如果一致的话,可以省去value属性。 @SessionAttribute注解,现在就可以在所有的方法中使用了
@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute(value = "users") String users){
System.out.println(users);
}
综合上述,session中存储的时名称为user的Session数据,此处@SessionAttribute绑定的时名称为users,因为users数据为空,此处会直接报错的,如下所示
org.springframework.web.bind.ServletRequestBindingException: Missing session attribute 'users' of type String
at org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver.handleMissingValue(SessionAttributeMethodArgumentResolver.java:56)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.handleMissingValue(AbstractNamedValueMethodArgumentResolver.java:215)
如果此处添加requires属性为false,说明参数不需要必须绑定,则此处不会出现上面错误
@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute(value = "users",required = false) String users){
System.out.println(users); ----不会报错,此处输出为null
}
13.@ModelAttribute
@ModelAttribute注解,会将请求到的参数绑定到相应的Model对象中
第一种
@Controller
public class HelloWorldController {
//发送请求:http://localhost:8080/helloWorld?abc=111
// 1.首先先执行firstVist
@ModelAttribute
public void firstVisit(@RequestParam String abc, Model model) {//2.赋值给abc后
model.addAttribute("attributeName", abc);//3.将abc塞入model的attributeName属性中
}
// 4.然后执行helloWorld方法
@RequestMapping(value = "/helloWorld")
public String helloWorld() {
return "getUser"; //5.跳转到getUser页面,页面通过EL表达式${attributeName}即可捕获到值为111
}
}
发送请求URL:http://localhost:8080/helloWorld?abc=111。被@ModelAttribute注解的firstVisit方法,会优于helloWorld先行调用。它会把请求参数首先赋值给由@RequestParam修饰的abc变量,然后执行model.addAttribute()方法,最后再执行helloWorld方法
第二种(@ModelAttribute注释返回指定具体类的方法)
@Controller
public class HelloWorldController {
//发送请求:http://localhost:8080/helloWorld
// 1.首先先执行firstVist
@ModelAttribute
public UserfirstVist(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {//2.请求连接无参数abc,所以此处abc获取默认值"nihao"
user.setUsername(abc);//3.将"nihao"赋值给user对象
return user;//4.此处返回User对象
}
// 5.然后执行helloWorld方法
@RequestMapping(value = "/helloWorld")
public StringhelloWorld() {
return "getUser";//6.此处直接跳转到页面,因为4中已经返回了User对象,所以在getUser页面中,通过EL表达式${user.username}仍然时可以访问到username属性的
}
}
第三种 (@ModelAttribute注释一个方法的参数,获取到由@ModelAttribute注释的firstVisit方法中的对象的值)
@Controller
public class HelloWorldController {
//发送请求:http://localhost:8080/helloWorld
// 1.首先先执行firstVist
@ModelAttribute
public void firstVist(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {//2.请求连接无参数abc,所以此处abc获取默认值"nihao"
user.setUsername(abc);//3.将"nihao"赋值给user对象
}
// 4.然后执行helloWorld方法
@RequestMapping(value = "/helloWorld")
public ModelAndView helloWorld(@ModelAttribute User user) {//5.由于之前User对象所在的方法时被@ModelAttribute注解修饰的,所以在此处可以通过@ModelAttribute来获取user对象信息
ModelAndView view = new ModelAndView("getUser");
view.addObject("user",user);//6.将user对象的信息set进view视图中去
return view;//7.跳转到getUser页面,通过EL表达式 ${user.username}即可获得数据"nihao"
}
}
第四种(由多个@ModelAttribute修饰的方法)
@Controller
public class HelloWorldController {
//发送请求:http://localhost:8080/helloWorld?abc=111&aaa=北京市
// 1.首先先执行firstModelttribute
@ModelAttribute
public User firstModelttribute(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {
user.setUsername(abc);
return user;
}
// 2.再执行secondModelttribute(两个被@ModelAttribute修饰的方法,根据顺序来先后执行,谁在前谁先执行)
@ModelAttribute
public User secondModelttribute(@RequestParam(required = false,defaultValue = "wori") String aaa, User user) {
user.setAddress(aaa);
return user;
}
@RequestMapping(value = "/helloWorld")
public ModelAndView helloWorld() {
ModelAndView view = new ModelAndView("getUser");
return view;
}
}
第五种(@ModelAttribute和@RequestMapping注释同一个方法)
@Controller
public class HelloWorldController {
@RequestMapping(value = "/helloWorld")
@ModelAttribute(value = "username")
public String helloWorld() {
return "getUser";
}
}
发送请求URL:http://localhost:8080/helloWorld
具体步骤:
①@ModelAttribute和@RequestMapping同时注释一个方法,则此时return "getUser"返回的并不是一个试图名称,而是model属性值,视图名称则时@RequestMapping的value值"/helloWorld"
②发送如上请求,如果helloWorld试图不存在时,直接会报404找不到
③此时,Model的属性名称是由@ModelAttribute中的value值指定。相当于request中封装了username(key)= getUser(value)
④跳转到helloWorld视图。通过EL表达式${username}就可以获取到值,值为getUser
⑤这种情况下,只能返回username一个属性。暂时也不知道如何返回到视图一个User对象,有待研究
14.@RequestBody
@RequestBody注解,会将ajax等请求中传递的Json对象的字符串,直接绑定到相对应的Bean实体类上,也可以将其分别绑定到对应的字符串上。。切记:接收的是一个Json对象的字符串,而不是一个Json对象。
通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,
然而在ajax请求往往传的都是Json对象,后来发现用 JSON.stringify(data)的方式就能将对象变成字符串。
@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。
$.ajax({
url:"/login",
type:"POST",
data:'{"userName":"admin","pwd","admin123"}',
content-type:"application/json",
success:function(data){
alert("request success ! ");
}
});
@requestMapping("/login")
//1.使用@RrequestBody将json数据分别绑定到相对应字符串上
public void login(@RequestBody String userName,@RequestBody String pwd){
System.out.println(userName+" :"+pwd);
}
//2.使用@RequestBody将json数据绑定到实体类bean上,[实体类Userr如下]
public void login(@RequestBody User user){
System.out.println(user.userName+" :"+user.pwd);
}
//实体类User
public class User {
private String userName;
private String pwd;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。
备注:在一些特殊情况@RequestBody也可以用来处理content-type类型为application/x-www-form-urlcoded的内容,只不过这种方式不是很常用,在处理这类请求的时候,@RequestBody会将处理结果放到一个MultiValueMap<String,String>中,这种情况一般在特殊情况下才会使用,
例如jQuery easyUI的datagrid请求数据的时候需要使用到这种方式、小型项目只创建一个POJO类的话也可以使用这种接受方式
15.@Conditional
@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
参考文章:@Conditional注解 详细讲解及示例
地址:
16.@ImportResource
@ImportResource注解:用于导入 Spring 的 xml 配置文件,让该配置文件中定义的 bean 对象加载到Spring容器中。
参考文章:@ImportResource 注解的使用
地址:
17.@PropertySource
@PropertySource注解:导入属性配置文件,配合@Value使用,来初始化Bean
参考文章:@PropertySource 注解的使用
地址:
18.@ConfigurationProperties
@ConfigurationProperties 注:配合 @Component 注解,可以批量注入配置文件中的属性。.
参考文章:注解@ConfigurationProperties 和 @Value 对比
地址:
19.Spring缓存相关注解
@Cacheable
@CacheEvict
@CachePut
@EnableCaching
参考文章:
1.Spring 缓存在项目中的使用 地址:
2.Spring Boot 缓存原理源码分析 地址:
3.@Cacheable注解属性介绍 地址:
4.Spring Boot 整合 Redis 实现数据缓存 地址:
20.@Scope
@Scope 注解是 Spring IOC 容器中的一个作用域,在 Spring IOC 容器中,他用来配置Bean实例的作用域对象
参考文章:@Scope注解 详细讲解及示例
地址:
21.@Lazy
懒汉方式创建
参考文章:@Scope注解 详细讲解及示例(有介绍@Lazy注解)
地址:
22.@Nullable、@NonNull
@NonNull 可以标注在方法、字段、参数之上,表示对应的值不可以为空
@Nullable 注解可以标注在方法、字段、参数之上,表示对应的值可以为空
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
public class Person {
private String name;
private int age;
private String address;
public Person(@Nullable String name, @Nullable int age, @NonNull String address) {
= name;
this.age = age;
this.address = address;
}
}
在通过构造器方式创建Person对象时,并不会报错,但是编译器会有提示,如下图所示。
以上两个注解在程序运行的过程中不会起任何作用,只会在IDE、编译器、FindBugs检查、生成文档的时候有做提示;
我使用的 IDE 是 Intellij IDEA,看网友说 STS 不会做自动的检查,只有安装了FindBugs插件并运行后会做对应的提示