大家好,又见面了,我是你们的朋友全栈君。
前言
这里我们不会将springboot全部的注解都一个一个分析一遍,因为现在普遍都是前后端分离开发,所以之前用在很多的模板视图解析上的注解现在已经不怎么用到了这里就没再提。有需要的同学可以去看我的其他关于框架的专栏。
Part.1:SpringMVC工作原理
因为springboot其实就是spring和SpringMVC的合体版本,所以分析它的注解其实就是分析spring和SpringMVC的注解,所以我们可以先看一下SpringMVC的工作原理(具体的解析可以看我的关于SpringMVC框架的专栏),因为它和我们的web层密切相关,而spring在这里充当的更多是一种管理者的角色(管理容器):
(因为是跟b站的一个up主学的,所以图也是直接那里截的,up主名叫小明哥2019,可以去看他的视频,我这里就是记录下来方便自己复习。) 如上图所示,右边那部分关于IOC的就是spring的东西了。 所谓的MVC:
part.2:Springboot常用注解
如上图所示,其中: 红色圈:springboot中的注解 黄色圈:SpringMVC中的注解 绿色圈:spring中的注册容器注解 紫色圈:spring中利用容器new对象的注解
下面开始总结:
@SpringBootApplication
这没啥好说的了,springboot自带的,是springboot项目的启动注解。
@Controller、@Repository、@Component、@Service
这个其实就是spring标志一个普通类作为一个IOC容器的注解,其作用就是标识这个类成为了一个IOC容器中的Bean工厂。作用与@Service、@Repository、@Component是一样的,名字不一样只是为了更好的区分三层架构,达到语义化的一个效果。如@Controller就是表示控制层的,@Repository就是表示数据层的,@Componment就是表示这三个哪一个都行,反正意思都一样。
@ResponseBody
在SpringMVC中因为控制器返回的是一个字符串,但这个字符串因为控制器在SpringMVC底层实现方式的原因,会被默认为返回是一个静态页面的名字然后以进行web页面的跳转,而加了这个注解之后控制器返回的字符串则就只是普通的字符串,不会再进行页面跳转了。 还可以提一嘴的是,如果我们前后端进行的是一个个对象的传输,则springboot因为内部已经替我们集成了一个json格式的转换工具(好像是fastjson,我忘了),所以如果传输的是对象,则自动就帮我们转换了json格式输出和写入而不需要我们自己进行json格式的转换。
@RequestBody
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。 注意:一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。 通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。 举个例子: 现在前端有一个请求:
代码语言:javascript复制$.ajax({
url:"/login",
type:"POST",
data:'{"userName":"admin","pwd","admin123"}',
content-type:"application/json charset=utf-8",
success:function(data){
alert("request success ! ");
}
});
然后现在后端有一个控制器:
代码语言:javascript复制@requestMapping("/login")
public void login(@requestBody String userName,@requestBody String pwd){
System.out.println(userName " :" pwd);
}
这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个User类,拥有如下字段: String userName; String pwd; 那么上述参数可以改为以下形式:@requestBody User user 这种形式会将JSON字符串中的值赋予user中对应的属性上 需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。
@RestController
@RestController注解相当于@ResponseBody + @Controller合在一起的作用。 因为前后端分离开发,后端的控制器不再需要返回作用为进行页面跳转的字符串,所以我们一般将这个注解加在整个控制器类的上面以表示下面所有的控制器方法通通都只返回普通字符串。
@RequestMapping
这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。并且一个处理请求地址映射的注解,可用在类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。 作用于方法上,则是作为请求 URL 的第二级访问目录。 总结就是:用于建立请求URL和处理请求方法之间的对应关系。(我们一般写类上,我也不知道为啥,应该是习惯叭)
@GetMapping、@PostMapping、@DeleteMapping、@PutMapping
@GetMapping是Spring4.3提供的新注解,它是一个组合注解,等价于@RequestMapping(method = RequestMethod.Get ),用于简化开发,注意:@RequestMapping如果没有指定请求方式,将接收Get、Post、Head、Options等所有的请求方式。同理还有@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping等。 这个注解一般我们用在方法上,我也不知道为啥,应该也是习惯叭,我遇见的项目都是这么写的。
@Autowired、@Quailifier、@Resource
代码语言:javascript复制package com.itheima.service.impl;
import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/* <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"> 等同于下面的@Service,注入id使用value */
@Service(value="userService")
public class UserServiceImpl implements UserService {
/*那属性的注入呢:<property name="userDao" ref="userDao"></property> 我们将使用Autowired和Qualifier */
/* Autowired是按照数据类型从Spring容器中进行匹配的,这里因为UserDao类型的只有一个实例就是 userDao,这里这里即使省去了@Qualifier也一样可以匹配到,但是如果UserDao类型有多个的话 只用Autowired就不好使了 */
// @Autowired
/* 而@Qualifier是按照id值从容器中进行匹配的,但是注意需要结合@Autowired才好使 */
// @Qualifier(value="userDao")
/* 或者也可以将上面的两个都去掉,改用@Resource(name="userDao"), 这个注解就相当于 @Autowired @Qualifier */
@Resource(name = "userDao")
private UserDao userDao;
//public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
//}
public void save() {
userDao.save();
}
}
@Configuration、@Bean等
如上图所示这些注解,其实是为了让我们能够完全脱离XML配置文件的方式使用Spring而出现的,之前的什么@Component注解啥的只能满足原生框架存在的Bean,但开发当中难免会遇到其他的Bean组件,比如配置数据源就缺少对应的注解代替XML。这个时候我们就可以使用这些注解来定义一个配置类,那么这个类就将作为Spring的核心配置文件类。 这其实就是把XML配置文件改成了Java形式的代码,然后用注解与Spring容器关联起来。在这个意义上,我们可以完全脱离配置文件去用Spring开发了,如下:
代码语言:javascript复制package com.itheima.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
//标志该类是Spring的核心配置类
@Configuration
//<context:component-scan base-package="com.itheima"></context:component-scan>
//扫哪个包则在参数里面声明
@ComponentScan("com.itheima")
// <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
@PropertySource("classpath:jdbc.properties")
public class SpirngConfiguration {
/* <!--配置c3p0数据源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> 上面这一段也可以被当成配置类的方法来使用注解解决 */
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String user;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource") //Spring会将当前方法的返回值以指定名称存储到Spring容器中
public DataSource getDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(user);
dataSource.setPassword(password);
return dataSource;
}
}
@RequestParam
这个注解的意思是接收从页面访问过来携带的请求参数,带?的这种。(这是前后端不分离情况下的,如果是分离的都是restful风格的了,不会有这种请求参数)
意思是我们在浏览器端输入url访问这个控制器时必须携带一个叫id的请求参数,默认必须要带否则报错,不过将required改成false之后就不是必须要带的了,defaultValue的作用是如果带的参数没有值则默认为自己设定的,上图就是0。
@PathVariable
处理向上图这种携带的参数,用斜杠的参数。
带斜杠的参数我们就可以用这个注解来解析两个斜杠中的占位符所代表的参数值,比如我们传的id值是1234,则占位符中{id}代表的就是1234,我们就可以用@PathVariable解析出来。
总结
没啥好总结的,差不多就是这些了我觉得。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/171239.html原文链接:https://javaforall.cn