JavaWeb常用注解
1. RequestBody
-
@RequestBody注解:将JSON数据映射到形参的实体类对象中(JSON中的key和实体类中的属性名保持一致)

@RestController
public class RequestController {
//JSON参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
}
2. @PathVariable
@RestController
public class RequestController {
//路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";
}
}
3. ResponseBody
-
@ResponseBody注解:
- 类型:方法注解、类注解
- 位置:书写在Controller方法上或类上
- 作用:将方法返回值直接响应给浏览器
- 如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器
但是在我们所书写的Controller中,只在类上添加了@RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?
@RestController public class HelloController { @RequestMapping("/hello") public String hello(){ System.out.println("Hello World ~"); return "Hello World ~"; } }原因:在类上添加的**@RestController注解,是一个组合注解**。
- @RestController = @Controller + @ResponseBody
@RestController源码:
@Target({ElementType.TYPE}) //元注解(修饰注解的注解) @Retention(RetentionPolicy.RUNTIME) //元注解 @Documented //元注解 @Controller @ResponseBody public @interface RestController { @AliasFor( annotation = Controller.class ) String value() default ""; }结论:在类上添加@RestController就相当于添加了@ResponseBody注解。
- 类上有@RestController注解或@ResponseBody注解时:表示当前类下所有的方法返回值做为响应数据
- 方法的返回值,如果是一个POJO对象或集合时,会先转换为JSON格式,在响应给浏览器
4. @Component 和 @Autowired
4.1 前置知识IOC & DI
-
控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器
-
依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
程序运行时需要某个资源,此时容器就为其提供这个资源。
例:EmpController程序运行时需要EmpService对象,Spring容器就为其提供并注入EmpService对象
@Component 注解可以实现类交给IOC容器管理
IOC容器中创建、管理的对象,称之为:bean对象
Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了@Component的衍生注解:
- @Controller (标注在控制层类上)
- @Service (标注在业务层类上)
- @Repository (标注在数据访问层类上)(后面使用Mybatis就变成@mapper了)
使用注解声明的bean,要想生效,还需要被组件扫描注解@ComponentScan扫描。@SpringBootApplication 中,默认扫描的范围是SpringBoot启动类所在包及其子包。
一般将我们定义的controller,service,dao这些包呢,都放在引导类所在包com.xxx的子包下,这样我们定义的bean就会被自动的扫描到
@Autowired 注解可以实现程序运行时IOC容器自动注入需要的依赖对象
5. @Data
使用@Data注解需要在pom.xm中引入lombok依赖
<!-- 如果在springboot的父工程中,已经集成了lombok并指定了版本号,引入依赖时就不需要指定version -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- 在实体类上添加了@Data注解,那么这个类在编译时期,就会生成getter/setter、equals、hashcode、toString等方法。
- @Data注解中不包含全参构造方法,通常在实体类上,还会添加上:全参构造、无参构造
import lombok.Data;
@Data //getter方法、setter方法、toString方法、hashCode方法、equals方法
@NoArgsConstructor //无参构造
@AllArgsConstructor//全参构造
public class User {
private Integer id;
private String name;
private Short age;
private Short gender;
private String phone;
}
6. @ConfigurationProperties
讲解完了yml配置文件之后,最后再来介绍一个注解@ConfigurationProperties。在介绍注解之前,我们先来看一个场景,分析下代码当中可能存在的问题:

我们在application.properties或者application.yml中配置了阿里云OSS的四项参数之后,如果java程序中需要这四项参数数据,我们直接通过@Value注解来进行注入。这种方式本身没有什么问题问题,但是如果说需要注入的属性较多(例:需要20多个参数数据),我们写起来就会比较繁琐。
那么有没有一种方式可以简化这些配置参数的注入呢?答案是肯定有,在Spring中给我们提供了一种简化方式,可以直接将配置文件中配置项的值自动的注入到对象的属性中。
Spring提供的简化方式套路:
-
需要创建一个实现类,且实体类中的属性名和配置文件当中key的名字必须要一致
比如:配置文件当中叫endpoints,实体类当中的属性也得叫endpoints,另外实体类当中的属性还需要提供 getter / setter方法
-
需要将实体类交给Spring的IOC容器管理,成为IOC容器当中的bean对象
-
在实体类上添加
@ConfigurationProperties注解,并通过perfect属性来指定配置参数项的前缀

实体类:AliOSSProperties
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/*阿里云OSS相关配置*/
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {
//区域
private String endpoint;
//身份ID
private String accessKeyId ;
//身份密钥
private String accessKeySecret ;
//存储空间
private String bucketName;
}
AliOSSUtils工具类:
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
@Component //当前类对象由Spring创建和管理
public class AliOSSUtils {
//注入配置参数实体类对象
@Autowired
private AliOSSProperties aliOSSProperties;
/**
* 实现上传图片到OSS
*/
public String upload(MultipartFile multipartFile) throws IOException {
// 获取上传的文件的输入流
InputStream inputStream = multipartFile.getInputStream();
// 避免文件覆盖
String originalFilename = multipartFile.getOriginalFilename();
String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
//上传文件到 OSS
OSS ossClient = new OSSClientBuilder().build(aliOSSProperties.getEndpoint(),
aliOSSProperties.getAccessKeyId(), aliOSSProperties.getAccessKeySecret());
ossClient.putObject(aliOSSProperties.getBucketName(), fileName, inputStream);
//文件访问路径
String url =aliOSSProperties.getEndpoint().split("//")[0] + "//" + aliOSSProperties.getBucketName() + "." + aliOSSProperties.getEndpoint().split("//")[1] + "/" + fileName;
// 关闭ossClient
ossClient.shutdown();
return url;// 把上传到oss的路径返回
}
}
在我们添加上注解后,会发现idea窗口上面出现一个红色警告:

这个警告提示是告知我们还需要引入一个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
当我们在pom.xml文件当中配置了这项依赖之后,我们重新启动服务,大家就会看到在properties或者是yml配置文件当中,就会提示阿里云 OSS 相关的配置项。所以这项依赖它的作用就是会自动的识别被@Configuration Properties注解标识的bean对象。
刚才的红色警告,已经变成了一个灰色的提示,提示我们需要重新运行springboot服务
@ConfigurationProperties注解我们已经介绍完了,接下来我们就来区分一下@ConfigurationProperties注解以及我们前面所介绍的另外一个@Value注解:
相同点:都是用来注入外部配置的属性的。
不同点:
- @Value注解只能一个一个的进行外部属性的注入。
- @ConfigurationProperties可以批量的将外部的属性配置注入到bean对象的属性中。
如果要注入的属性非常的多,并且还想做到复用,就可以定义这么一个bean对象。通过 configuration properties 批量的将外部的属性配置直接注入到 bin 对象的属性当中。在其他的类当中,我要想获取到注入进来的属性,我直接注入 bin 对象,然后调用 get 方法,就可以获取到对应的属性值了
7. @Transactional
-
@Transactional作用:就是在当前这个方法执行开始之前来开启事务,方法执行完毕之后提交事务。如果在这个方法执行的过程当中出现了异常,就会进行事务的回滚操作。
-
@Transactional注解:我们一般会在业务层当中来控制事务,因为在业务层当中,一个业务功能可能会包含多个数据访问的操作。在业务层来控制事务,我们就可以将多个数据访问操作控制在一个事务范围内。
-
@Transactional注解书写位置:
- 方法上
- 当前方法交给spring进行事务管理
- 类上
- 当前类中所有的方法都交由spring进行事务管理
- 接口上
- 接口下所有的实现类当中所有的方法都交给spring 进行事务管理
- 方法上
-
在业务方法delete上加上 @Transactional 来控制事务
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private EmpMapper empMapper;
@Override
@Transactional //当前方法添加了事务管理
public void delete(Integer id){
//根据部门id删除部门信息
deptMapper.deleteById(id);
//模拟:异常发生
int i = 1/0;
//删除部门下的所有员工信息
empMapper.deleteByDeptId(id);
}
}
// 添加Spring事务管理后,由于服务端程序引发了异常,所以事务进行回滚。有了事务管理后就不会出现部门id会被删除的情况,保证事务操作前后数据的一致性
1173

被折叠的 条评论
为什么被折叠?



