目录
@Configuation总结: @Configuation等价于 @Bean等价于 @ComponentScan等价于
6.@TableName、 @TableId、 @TableField注解
7.有关@Component、@Service、@Controller、@Repository注解
8.有关@Autowired、@Qualifier、@Resource、@Value注解
10.@EnableConfigurationProperties注解
11.@DurationUnit注解与@DataSizeUnit注解
12.Bean属性校验有关的注解@Validated、@MAX、@MIN
15.关于@Transactional与@RollBack注解
2.解决“未配置Springboot配置注释处理器” 问题的maven坐标 参考注解9
一、注解
1. 关于 @Slf4j 注解的使用说明
作用:帮我们创建一个Logger对象,如下图代码所示
private static final Logger log= LoggerFactory.getLogger(BooksController.class);
此注解使用在类名之上,如下图代码所示
@Slf4j
@RestController
@RequestMapping("/books")
public class BooksController {
// 创建记录日志的对象
// private static final Logger log= LoggerFactory.getLogger(BooksController.class);
@GetMapping
public String getById(){
System.out.println("springboot is running");
log.trace("trace..."); //这个级别太低,基本上没人用
log.debug("debug...");
log.info("info...");
log.warn("warn....");
log.error("error....");
// 其实后面还有一个fatal 但是在idea中将fatal和error合二为一了
return "springboot is running";
}
}
使用前提,导入Maven坐标:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2. @Configuration 注解
作用:用于定义配置类,可替换xml配置文件,被注解的类内部包含一个或多个被@Bean注解的方法,这些方法将会被`AnnotationConfigApplicationContext`或`AnnotationConfigWebApplicationContext`类(启动类)进行扫描,并用于构建bean(创建bean对象),初始化Spring容器。
例子:
//拦截器
@Configuration //第一步:配置类 交给Spring管理 确保在启动类的包或子包下,才能被扫描到
public class NPCConfig {
// 第二步:做对应Bean
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
// 第三步:创建拦截器(这只是一个壳子)
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 第四步:添加内部拦截器 (分页的)
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
// 可以添加多个内部拦截器
return interceptor;
}
}
注意 :
@Configuration配置spring并启动spring容器
@Configuration启动容器+@Bean注册Bean
@Configuration启动容器+@Component注册Bean
@Configuration不可以是final类型;
@Configuration不可以是匿名类;
嵌套的configuration必须是静态类。
@Configuation总结:
@Configuation等价于<Beans></Beans>
@Bean等价于 <Bean></Bean>
@ComponentScan等价于<context:component-scan base-package=”com.dxz.demo”/>
补充:
<Beans></Beans>作用:在spring配置文件pom.xml中,所有的代码都是在此标签之中开始书写的
<Bean></Bean>作用:这个是在spring中的Bean管理操作,使用此标签进行创建对象和注入属性
<bean id="book" class="com.spring5.Book">
<!--在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可实现对象的创建-->
<!--使用property标签完成属性的注入,其中name属性值要和Book类中的属性名对应-->
<property name="bookName" value="易筋经" ></property>
<context:component-scan base-package=”com.dxz.demo" />:Bean管理的一种方式,基于注解方式实现对 对象的创建。当我们使用这种方式的时候,开启组件扫描就需要这段代码。“base-package”属性值可以一个或者多个包,多个包的话可以使用逗号隔开。
具体的注解解释可以参考下面链接中的文章:
http://t.csdn.cn/dhgoW
3.灌入REST风格有关的注解
理解:
使用REST风格对资源进行访问称为RESTFUL
http://localhost/books 查询全部用户信息 Get 查询
http://localhost/books/id 查询指定用户信息 Get 查询
http://localhost/books 添加某个用户信息 Post (新增、保存)
http://localhost/books 修改用户用户信息 Put (修改、更新)
http://localhost/books/id 删除某个用户信息 Delete
例子:
/*@Controller
@ResponseBody 可以把每个方法提上面的 @ResponseBody注解,提取到这里 //@RequestBody请求体参数 都是传JSON数据过来*/
@RestController//@Controller + @ResponseBody = RestController
@RequestMapping(value="/users") //通过观察,我们下面的@RequestMapping注解中有共同的"/users"部分,所以我们把他提取出来
public class UserController {
@RequestMapping //这个注解可以代替下面这一句代码
// @RequestMapping(value="/users",method = RequestMethod.POST)//method = RequestMethod.POST 限定提交方式,在这里采用POST方式发送提交
// @ResponseBody
public String save(){
System.out.println("user save....");//在控制台中显示
return "{module:user save}"; //这个内容会在页面显示 http://localhost:8080/users
}
@DeleteMapping("{id}")//这个注解可以代替下面这一句代码
// @RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
// @ResponseBody
public String delete(@PathVariable Integer id){ //@PathVariable 路径变量参数 这个地方的id要和路径中的id 名字要一致,变量名同
System.out.println("user delete:"+id);
return "{module:user delete}";
}
@RequestMapping
// @RequestMapping(value="/users",method = RequestMethod.PUT)
// @ResponseBody
public String update (@PathVariable User user){
System.out.println(user);
return "user update";
}
@GetMapping("{id}")
// @RequestMapping(value="/users/{id}",method = RequestMethod.GET)
// @ResponseBody
public String getById(@PathVariable Integer id){ //@PathVariable 这个注解表示形参注解,绑定路径参数与处理器方法形参减的关系;如果不写这个的话,获取不到网页传来的数据
System.out.println(id);
return "user update";
}
}
前提:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
4.@RestControllerAdvice注解
理解:
@RestControllerAdvice是一个组合注解,由@ControllerAdvice+@ResponseBody组成,而 @ControllerAdvice继承了@Component,因此@RestControllerAdvice本质上是个Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
特点:
①通过@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置。
②注解了@RestControllerAdvice的类的方法可以使用@ExceptionHandler、@InitBinder、 @ModelAttribute注解到方法上。
③@RestControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上。
④@ExceptionHandler:用于指定异常处理方法。当与@RestControllerAdvice配合使用时,用于全局处理控制器里的异常。
⑤@InitBinder:用来设置WebDataBinder,用于自动绑定前台请求参数到Model中。
⑥@ModelAttribute:本来作用是绑定键值对到Model中,当与@ControllerAdvice配合使用时,可以让全局的@RequestMapping都能获得在此处设置的键值对
例子:
//作为springMVC的异常处理器
//数据层业务层的异常最终会抛的表现层
//@ControllerAdvice
@RestControllerAdvice //里面还有一个bean
public class ProjectExceptionAdvice {
// 这个方法拦截所有的异常信息
@ExceptionHandler // 这个注解可以加参数:具体拦截什么异常 @ExceptionHandler(value = NullPointerException.class) public R doException(Exception e){
// 记录日志,通知运维,通知开发
e.printStackTrace(); //出异常信息
return new R(false,"服务器故障,请稍后再试");
}
}
原文链接:https://blog.csdn.net/user2025/article/details/105458842
5.@Data注解
作用:
此时表示R类实现了get+set+toString+hashcode+equals方法
注意!!!!!并没有实现构造方法
@Data
public class R{}
@Getter在本类中创造所有的get方法
@Setterr在本类中创造所有的set方法
@NoArgsrConstructorr在本类中创造 无参构造方法
@AllArgsConstructorr在本类中创造全部的构造方法
使用前提:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
5.@Mapper注解
例子:
@Mapper //通过这个实现数据库的操作 里面有数据库中各种各样的操作
public interface BookDao extends BaseMapper<Book> {//指定泛型才能知道操作谁
}
可以实现数据库的基本操作,比如增删改查操作
前提:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
例子:
@SpringBootTest
class StudentScoreApplicationTests {
@Autowired
private StudentDao studentDao;
@Test
void testGetById(){
studentDao.selectById(202001);
}
@Test
void contextLoads() {
}
}
6.@TableName、 @TableId、 @TableField注解
@Data //get+set+toString+hashcode+equals 但是没有构造方法
@TableName(value = "t_book")
public class Book {
// 这里的属性名 要和数据库表中的属性名一致,要不然最终的查询结果是null
// 将数据库中的结果对此变量名进行注入
@TableId(value="id",type = IdType.AUTO) //代表自增算法
@TableField(value = "id")
private int id;
@TableField(value = "bookName")
private String bookName;
@TableField(value = "statue")
private String statue;
@TableField(value="type")
private String type;
}
使用前提:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
7.有关@Component、@Service、@Controller、@Repository注解
作用:
上面这四个注解功能都是一个样的,都是用来创建bean实例的,也可以混合使用,但是为了方便编程,我们一般把不同的注解放到不同的层中
@Component注解:
把普通pojo实例化到spring容器中,相当于配置文件中的 `<bean id="" class=""/>`
@Service服务注解:
注入dao(dao通俗来讲就是将数据库操作都封装起来),用于标注服务层,主要用来进行业务的逻辑处理
@Controller控制器注解:
注入服务,用于标注控制层,相当于struts中的action层
@Repository注解:
用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件
原文连接:http://t.csdn.cn/5BmKs
8.有关@Autowired、@Qualifier、@Resource、@Value注解
@Autowired注解:
作用:根据属性类型进行自动装配,以后就不用在配置文件中bean实例创建对象了
@Autowired
private BookDao bookDao; //添加根据类型注入属性的注解,定义一个BookDao类型的注解,不再需要我们添加set方法,在这个里面已经给我们封装好了
@Qualifier注解:
作用:根据属性名称进行注入
如下面例子所示,UserDao类型的属性根据名称”UserDaoImpl1“进行对应,然后进行更加准确的注入。
@Service
public class UserService{
@Autowired
@Qualifier (value="userDaoImpl1")
private UserDao userDao;
}
@Repository (value="userDaoImpl1")
public class UserDaoImpl implements UserDao{
@Override
public void add(){
System.out.println("dao add...");
}
}
为什么会有这种方法? 因为当UserDao有多个实现类的时候,我们仅仅使用一个@Autowired注解无法准确的判断我们到底要注入哪个实现类,故有了此种方式来进行实现。
@Resource注解
作用:可以根据类型注入,也可以根据名称注入(本身不是spring里面的,而是java扩展包里面的)
@Service //此时是根据类型注入
public class UserService{
@Resource
private UserDao userDao
}
@Service //此时是根据名称注入
public class UserService{
@Resource (name="userDaoImpl1")
private UserDao userDao
}
@Value注解:
作用:注入普通类型属性
@Service
public class UserService{
@Value(value="abc")
private String name; //此时name就是abc
}
其他用法:
从配置文件中读取相应的配置
9.@ConfigurationProperties注解
①使用此注解绑定非第三方属性
②使用此注解为第三方bean绑定属性
代码例子:
@Data //没有构造方法
@Component //最终要加载配置中对应的属性,这个类要受spring的管控,我们要把它配置成bean
@ConfigurationProperties( prefix="servers") //profix:前缀,把属性名对应的上一级,写在这个地方,若有多个层级,可写成A.B.C.servers
public class ServerConfig {
private String ipAddress;
private int port;
private long timeout;
}
@SpringBootApplication
public class Springboot13ConfigurationApplication {
@Bean
@ConfigurationProperties(prefix = "datasource") //将datasource层级下的内容注入到下面这个对象中去
public DruidDataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
// ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
return ds;
}
public static void main(String[] args) {
//类似spring5的那种方式
ConfigurableApplicationContext ctx = SpringApplication.run(Springboot13ConfigurationApplication.class, args);
ServerConfig bean= ctx.getBean(ServerConfig.class); //拿到对象
System.out.println(bean);
// 获取第三方bean
DruidDataSource ds = ctx.getBean(DruidDataSource.class);
System.out.println(ds.getDriverClassName());
}
}
# 下面这种方法是配置端口
#server:
# port:
# 下面的这个三个属性要和Servlet类中的属性进行对应
servers:
ipAddress: 192.168.0.1
timeout: -1
port: 2345
datasource:
driverClassName: com.mysql.cj.jdbc.Driver456
10.@EnableConfigurationProperties注解
这个注解和@ConfigurationProperties注解有点相似
@EnableConfigurationProperties好处:
可以了解哪些属性是从配置中读取的,让我们的程序不是那么的松散。
开启属性绑定,并让设定属性绑定的目标是谁
如果仅仅写@EnableConfigurationProperties注解是会报错的,后面一定要跟着参数
@ConfigurationProperties:
具体的做属性绑定的
在注解前面加Enable,可以理解为一个开关
使用方法:
@Component代表定义了一个Bean
@EnableConfigurationProperties({ServerConfig.class}),告诉spring容器,现在有一组信息要去加载配置,说明这个必须是Bean才能被加载,顾默认将ServerConfig.class加载成了Bean
特此说明,如果@Component与@EnableConfigurationProperties一起使用,会造成异常,因为Bean了两次!!!
这种情况下,我们把@Component注解删除就好了
@SpringBootApplication
@EnableConfigurationProperties({ServerConfig.class})
public class Springboot13ConfigurationApplication {
@Bean
@ConfigurationProperties(prefix = "datasource") //将datasource层级下的内容注入到下面这个对象中去
public DruidDataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
// ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
return ds;
}
public static void main(String[] args) {
//类似spring5的那种方式
ConfigurableApplicationContext ctx = SpringApplication.run(Springboot13ConfigurationApplication.class, args);
ServerConfig bean= ctx.getBean(ServerConfig.class); //拿到对象
System.out.println(bean);
// 获取第三方bean
DruidDataSource ds = ctx.getBean(DruidDataSource.class);
System.out.println(ds.getDriverClassName());
}
}
@Data //没有构造方法
//@Component //最终要加载配置中对应的属性,这个类要受spring的管控,我们要把它配置成bean
@ConfigurationProperties( prefix="servers") //profix:前缀,把属性名对应的上一级,写在这个地方,若有多个层级,可写成A.B.C.servers
public class ServerConfig {
private String ipAddress;
private int port;
private long timeout;
}
11.@DurationUnit注解与@DataSizeUnit注解
@DurationUnit注解: 提供时间计量单位 (如果不写的话,默认毫秒)
@DataSizeUnit注解:提供存储空间的大小(如果不写的话,默认B)
12.Bean属性校验有关的注解@Validated、@MAX、@MIN
第一步:导入相关的maven坐标,参考下面的坐标
代码举例:
@Data
@ConfigurationProperties( prefix="servers")
@Validated //第二步:开启对当前Bean的属性注入校验
public class ServerConfig {
private String ipAddress;
@Max(value = 8888,message = "最大值不能超过8888") //第三步:开启校验
@Min(value = 202,message = "最小值不能小于202")
private int port;
private long timeout;
}
@SpringBootApplication
@EnableConfigurationProperties({ServerConfig.class})
public class Springboot13ConfigurationApplication {
@Bean
@ConfigurationProperties(prefix = "datasource") //将datasource层级下的内容注入到下面这个对象中去
public DruidDataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
// ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
return ds;
}
public static void main(String[] args) {
//类似spring5的那种方式
ConfigurableApplicationContext ctx = SpringApplication.run(Springboot13ConfigurationApplication.class, args);
ServerConfig bean= ctx.getBean(ServerConfig.class); //拿到对象
System.out.println(bean);
// 获取第三方bean
DruidDataSource ds = ctx.getBean(DruidDataSource.class);
System.out.println(ds.getDriverClassName());
}
}
13.@Import注解使用
使用import注解加载当前测试类专用的配置
代码:
@Configuration
public class MsgConfig {
@Bean
public String msg(){
return "bean msg";
}
}
@SpringBootTest
@Import({MsgConfig.class}) //又追加了一个Msg.class配置
public class ConfigurationTest {
@Autowired
private String msg;
@Test
void testConfig(){
System.out.println(msg);
}
}
14.@SpringBootTest完成web环境模拟测试
发送虚拟请求
@Test
void Test(@Autowired MockMvc mvc){
// 创建虚拟请求,当前访问 /books
RequestBuilder builder = MockMvcRequestBuilders.get("/books");
try {
// 执行对应的请求
mvc.perform(builder);
} catch (Exception e) {
e.printStackTrace();
}
}
匹配相应执行状态:
//开启web环境
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc //开启虚拟MVC调用
public class WebTest {
@Test
void testStatus(@Autowired MockMvc mvc){
// 创建虚拟请求,当前访问 /books
RequestBuilder builder = MockMvcRequestBuilders.get("/books");
try {
// 执行对应的请求
ResultActions actions = mvc.perform(builder);
// 设定预期值,与真实值比较, 成功通过测试,失败测试失败
// 定义执行状态匹配器
StatusResultMatchers status = MockMvcResultMatchers.status();
// 预计本次调用时成功的,状态200
ResultMatcher ok = status.isOk();
// 使用本次真实执行的结果与预期结果进行对比
actions.andExpect(ok);
} catch (Exception e) {
e.printStackTrace();
}
}
}
匹配响应体:
//开启web环境
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc //开启虚拟MVC调用
public class WebTest {
@Test
void testBody(@Autowired MockMvc mvc){
// 创建虚拟请求,当前访问 /books
RequestBuilder builder = MockMvcRequestBuilders.get("/books");
try {
// 执行对应的请求
ResultActions actions = mvc.perform(builder);
// 设定预期值,与真实值比较, 成功通过测试,失败测试失败
// 定义执行状态匹配器
ContentResultMatchers content= MockMvcResultMatchers.content();
// 定义预期执行结果
ResultMatcher result = content.string("springboot2");
// 使用本次真实执行的结果与预期结果进行对比
actions.andExpect(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
匹配响应体JSON
@Test
void testJson(@Autowired MockMvc mvc){
// 创建虚拟请求,当前访问 /books
RequestBuilder builder = MockMvcRequestBuilders.get("/books");
try {
// 执行对应的请求
ResultActions actions = mvc.perform(builder);
// 设定预期值,与真实值比较, 成功通过测试,失败测试失败
// 定义执行状态匹配器
ContentResultMatchers content= MockMvcResultMatchers.content();
// 定义预期执行结果
ResultMatcher result = content.json("{\"id\":1,\"name\":\"zhang\",\"type\":\"5555\",\"description\":\"66666\"}");
// 使用本次真实执行的结果与预期结果进行对比
actions.andExpect(result);
} catch (Exception e) {
e.printStackTrace();
}
}
匹配响应头:
@Test
void testContentType(@Autowired MockMvc mvc){
// 创建虚拟请求,当前访问 /books
RequestBuilder builder = MockMvcRequestBuilders.get("/books");
try {
// 执行对应的请求
ResultActions actions = mvc.perform(builder);
// 设定预期值,与真实值比较, 成功通过测试,失败测试失败
// 定义执行状态匹配器
HandlerResultMatchers header= MockMvcResultMatchers.handler();
// 定义预期执行结果
ResultMatcher contentType = header.string("Content.Type","application/json");
// 使用本次真实执行的结果与预期结果进行对比
actions.andExpect(contentType);
} catch (Exception e) {
e.printStackTrace();
}
}
链接!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
http://t.csdn.cn/Miwkchttp://t.csdn.cn/Miwkc
下列的这个语句,模拟了get请求
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String getById(){
System.out.println("getById is running");
return "springboot";
}
}
有下列四种参数
15.关于@Transactional与@RollBack注解
业务层测试事物回滚,当测试需对数据库进行操作,但操作时不会给数据库留下任何的痕迹
避免产生了垃圾数据
@SpringBootTest
@Transactional
@RollBack(true) //默认为true,当为true的时候可以不写这个注解;false表示不会回滚,即是有@Transactional注解也不会回滚
public class Test{
@Autowired
private BookService bookService
@Test
void testSave(){
Book book = new Book();
bookService.save(book);
//虽然执行了保存对象的语句,但是数据库中并没有这一条数据,防止测试时留下垃圾数据
}
}
二、常用maven坐标
1. lombok坐标的使用,参照注解1 与注解5
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.解决“未配置Springboot配置注释处理器” 问题的maven坐标 参考注解9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3.Bean属性校验Maven坐标
这是一组规范,专门做数据校验的
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
4.使用hibernate框架提供的校验器做实现类
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>