1.Spring常用注解
分类 | 注解 | 位置 | 对应的XML标签 | 作用 |
---|---|---|---|---|
声明bean 的注解 | @Component | 类 | <bean> | 最普通的组件,可以被注入到spring容器进行管理,没有明确的角色 |
@Service | 在业务逻辑层使用(service层) | |||
@Repository | 在持久层(数据访问层)使用(dao层) | |||
@Controller | 在表现层使用,控制器的声明(spring-mvc的注解) | |||
@Bean | 用于将一个方法返回的对象注册到Spring容器中 | |||
注入bean 的注解 | @Autowired | 属性 | <property> | 默认先按类型进行匹配,如果发现找到多个bean,则又按照名称方式进行匹配 |
@Qualifier | 指定注入Bean的名称,如果容器中有一个以上匹配的Bean则可以通过@Qualifier注解限定Bean的名称 | |||
@Primary | 当系统中需要配置多个具有相同类型的bean时,@Primary可以定义这些Bean的优先级 | |||
@Resource | 通过其唯一的名称来标识特定的目标组件 | |||
声明Bean 范围的注解 | @Scope | 类 | scope属性 | 改变bean作用范围的注解 |
切面(AOP) 相关注解 | @Aspect | 类 | <aop:aspect> | 把当前类声明为切面类 |
@PointCut | <aop:pointcut> | 用于定义一个切入点(Pointcut), 切入点定义了哪些方法应该被拦截(即哪些方法会被增强) | ||
@Before | 方法 | <aop:before> | 前置通知,可以指定切入点表达式 | |
@Around | <aop:around> | 环绕通知,可以指定切入点表达式 | ||
@AfterReturning | <aop:after-returning> | 后置【try】通知,可以指定切入点表达式 | ||
@AfterThrowing | <aop:after-throwing> | 异常【catch】通知,可以指定切入点表达式 | ||
@After | <aop:after> | 最终【finally】通知,可以指定切入点表达式 | ||
@Enable*注解说明 | @EnableWebMvc | 类 | <mvc:annotation-driven> | 开启Web MVC的配置支持 |
@EnableAspectJAutoProxy | <aop:aspectj-autoproxy> | 开启spring对注解AOP的支持 | ||
@EnableTransactionManagement | <tx:annotation-driven> | 开启注解式事务的支持 | ||
@EnableCaching | <cache> | 开启注解式的缓存支持 | ||
测试相关注解 | @RunWith | 类 | @RunWith 是 JUnit 框架提供的一个注解,它允许 使用不同的运行器来运行测试类 | |
@ContextConfiguration | 定 Spring 上下文配置信息,告诉测试类在运行测试时应该加载哪些配置文件或者配置类 | |||
Spring MVC相关注解 | ||||
Spring MVC 核心注解 | @RestController | 类 | <bean> | 组合注解,等同于 @Controller+ @ResponseBody, 用于标识 RESTful Web Services |
@RequestMapping | 类/方法 | 用于将 HTTP 请求映射到对应的方法上。 | ||
数据绑定注解 | @RequestParam | 方法 | 用于将请求参数与控制器方法的参数进行绑定 | |
@PathVariable | 用于将 URI 模板变量与控制器方法的参数进行绑定 | |||
@RequestBody | 用于读取 Http 请求的正文,将其绑定到相应的 bean 上 | |||
@ResponseBody | 表示该方法的返回结果直接作为 Web 响应正文返回,用于异步请求处理。 | |||
事务 | @Transactional | 类/方法 | 在类或者方法上开启事务 |
Spring Boot相关注解可参考:Spring Boot常用注解
2.声明Bean的注解
@Component
@Component
注解用于标注一个普通的组件类,它没有明确的业务范围,只是通知Spring被此注解的类需要被纳入到Spring Bean容器中并进行管理。此注解的使用示例如下:
@Component
public class TestComponent {
......
}
@Controller
@Controller
是@Component
注解的一个延伸,会自动扫描并配置被该注解标注的类。
此注解用于标注Spring MVC的控制器。下面是使用此注解的示例代码:
@Controller
public class UserController{
......
}
@Service
@Service
注解是@Component
的一个延伸(特例),它用于标注业务逻辑类。
与@Component
注解一样,被此注解标注的类,会自动被Spring所管理。下面是使用@Service
注解的示例:
@Service
public class UserService {
......
}
@Repository
@Repository
注解也是@Component
注解的延伸,与@Component
注解一样,被此注解标注的类会被Spring自动管理起来。
@Repository
注解用于标注DAO层的数据持久化类。此注解的用法如下:
@Repository
public class UserMapper {
......
}
@Bean
用于将一个方法返回的对象注册到Spring容器中。
@Bean
是Spring框架中的一个注解,用于将一个方法返回的对象注册为一个Spring Bean。
用法如下:
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserServiceImpl();
}
@Bean
public UserRepository userRepository() {
return new UserRepositoryImpl();
}
3.注入Bean的注解
@Autowired
@Autowired
注解用于标记Spring将要解析和注入的依赖项。此注解可以作用在构造函数、字段和setter方法上。
默认情况下spring是按照类型装配的,也就是我们所说的byType
方式
- 成员变量
在成员变量上使用Autowired注解:
@Service
public class UserService {
@Autowired
private IUser user;
}
这种方式可能是平时用得最多的。
- 构造器
在构造器上使用Autowired注解:
@Service
public class UserService {
private IUser user;
@Autowired
public UserService(IUser user) {
this.user = user;
System.out.println("user:" + user);
}
}
注意,在构造器上加Autowired注解,实际上还是使用了Autowired装配方式,并非构造器装配。
- 方法
- 在普通方法上加Autowired注解:
@Service
public class UserService {
@Autowired
public void test(IUser user) {
user.say();
}
}
spring会在项目启动的过程中,自动调用一次加了@Autowired注解的方法,我们可以在该方法做一些初始化的工作。
- 也可以在setter方法上Autowired注解:
@Service
public class UserService {
private IUser user;
@Autowired
public void setUser(IUser user) {
this.user = user;
}
}
- 参数
- 可以在构造器的入参上加Autowired注解:
@Service
public class UserService {
private IUser user;
public UserService(@Autowired IUser user) {
this.user = user;
System.out.println("user:" + user);
}
}
- 也可以在非静态方法的入参上加Autowired注解:
@Service
public class UserService {
public void test(@Autowired IUser user) {
user.say();
}
}
@Qualifier
当系统中存在同一类型的多个Bean时,@Autowired
在进行依赖注入的时候就不知道该选择哪一个实现类进行注入。
此时,我们可以使用@Qualifier
注解来指定某个Bean的具体名称,示例:
@Service
public class UserService {
@Autowired
@Qualifier("user1")
private IUser user;
}
@Primary
除了上面的@Qualifier
注解之外,还能使用@Primary注解解决上面的问题。当系统中需要配置多个具有相同类型的bean时,@Primary可以定义这些Bean的优先级,比如在User1上面加上@Primary
注解:
@Primary
@Service
public class User1 implements IUser{
@Override
public void say() {
}
}
当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有@Primary
注解修饰,该候选者会被选中,作为自动配置的值。
@Resource
@Resource
默认按照byName进行属性注入,如果通过name无法找到相应的bean实例,接着就通过byType进行匹配。
按照byType匹配的逻辑和@Autowired匹配走的是同一套逻辑,所以@Resource
的匹配逻辑为byName -> byType -> byName
。
@Service
public class UserService {
@Resource
private IUser user;
}
4.声明Bean范围的注解
@Scope
声明 Spring Bean 的作用域,使用方法:
@Bean
@Scope("singleton")
public Person personSingleton() {
return new Person();
}
四种常见的 Spring Bean 的作用域:
singleton
: 唯一 bean 实例,Spring 中的 bean 默认都是单例的。prototype
: 每次请求都会创建一个新的 bean 实例。request
: 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。session
: 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
5.切面(AOP)相关注解
@Aspect
用于定义切面,@Aspect
是Spring框架中的一个注解,用于标识一个类为切面类,从而可以在该类中定义切面逻辑以实现AOP(面向切面编程)。
在Spring框架中,如果需要使用AOP来实现某些功能,我们可以使用@Aspect
注解来标识一个类为切面类。在切面类中,我们可以定义切面逻辑,包括切入点、通知类型和切面顺序等,从而实现AOP编程的功能。
用例:
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.example.UserService.*(..))")
public void beforeAdvice() {
System.out.println("Before advice is executed.");
}
@After("execution(* com.example.UserService.*(..))")
public void afterAdvice() {
System.out.println("After advice is executed.");
}
}
这个类使用@Aspect注解标识,表示这个类是一个切面类。同时,我们还使用@Component注解标识这个类,以便Spring框架能够自动将它加入到Spring容器中。
在这个例子中,我们定义了一个MyAspect类来实现某些功能的切面编程。在这个类中,我们定义了两个通知类型,即@Before和@After,分别表示在目标方法执行前和执行后执行某些操作。这些通知类型的执行条件是通过切入点表达式来定义的。
@Pointcut
用来定义一个切入点,即某件事情的入口。切入点决定了连接点关注的内容,使得我们可以控制通知什么时候执行。
@Aspect
@Component
public class LogAspectHandler {
/**
* 定义一个切面,拦截com.hong.controller包和子包下的所有方法
*/
@Pointcut("execution(* com.hong.controller..*.*(..))")
public void pointCut() {}
}
@Pointcut注解指定一个切面,定义需要拦截的东西,这里介绍两个常用的表达式:一个是使用 execution()
,另一个是使用annotation()
。
以execution(* com.hong.controller….(…))) 表达式为例,语法如下:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
- 例如:
execution(* com.by.service.UserService.add(..))
execution(* com.by.service.UserService.*(..))
execution(* com.by.service.*.*(..))
- 通配符解释:
*
:匹配任意字符,只匹配⼀个元素(返回类型, 包, 类名, 方法或者方法参数)
..
:匹配多个连续的任意符号, 可以通配任意层级的包, 或任意类型, 任意个数的参数
annotation()
方式是针对某个注解来定义切面,比如我们对具有 @GetMapping 注解的方法做切面,
可以如下定义切面:
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
public void annotationCut() {}
然后使用该切面的话,就会切入注解是@GetMapping的方法。
@Before
用于在方法执行前执行通知。
@Before
是Spring框架中的一个注解,用于定义在目标方法执行前执行的通知类型,以实现AOP(面向切面编程)。
用例:
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.example.UserService.*(..))")
public void beforeAdvice() {
System.out.println("Before advice is executed.");
}
}
@After
用于在方法执行后执行通知。
@After
是Spring框架中的一个注解,用于定义在目标方法执行后执行的通知类型,以实现AOP(面向切面编程)。
用例:
@Aspect
@Component
public class MyAspect {
@After("execution(* com.example.UserService.*(..))")
public void afterAdvice() {
System.out.println("After advice is executed.");
}
}
@Around
用于在方法执行前后执行通知。
@Around
是Spring框架中的一个注解,用于定义在目标方法执行前后执行的通知类型,以实现AOP(面向切面编程)。
用例:
@Aspect
@Component
public class MyAspect {
@Around("execution(* com.example.UserService.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before advice is executed.");
Object result = joinPoint.proceed();
System.out.println("After advice is executed.");
return result;
}
}
@AfterReturning
用于在方法返回结果后执行通知。
@AfterReturning
是Spring框架中的一个注解,用于定义在目标方法返回结果后执行的通知类型,以实现AOP(面向切面编程)。
用例:
@Aspect
@Component
public class MyAspect {
@AfterReturning(pointcut = "execution(* com.example.UserService.*(..))", returning = "result")
public void afterReturningAdvice(Object result) {
System.out.println("After returning advice is executed. Result is " + result);
}
}
@AfterThrowing
用于在方法抛出异常后执行通知。
@AfterThrowing
是Spring框架中的一个注解,用于定义在目标方法抛出异常后执行的通知类型,以实现AOP(面向切面编程)。
用例:
@Aspect
@Component
public class MyAspect {
@AfterThrowing(pointcut = "execution(* com.example.UserService.*(..))", throwing = "ex")
public void afterThrowingAdvice(Exception ex) {
System.out.println("After throwing advice is executed. Exception is " + ex);
}
}
6. 处理常见的HTTP请求类型
@RequestMapping
@RequestMapping注解的主要用途是将Web请求与请求处理类中的方法进行映射。Spring MVC和Spring WebFlux都通过RquestMappingHandlerMapping
和RequestMappingHndlerAdapter
两个类来提供对@RequestMapping注解的支持。
@RequestMapping
注解对请求处理类中的请求处理方法进行标注;@RequestMapping
注解拥有以下的六个配置属性:
-
value
:映射的请求URL或者其别名
5 种常见的请求类型:GET
:请求从服务器获取特定资源。举个例子:GET /users(获取所有学生)POST
:在服务器上创建一个新的资源。举个例子:POST /users(创建学生)PUT
:更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的学生)DELETE
:从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的学生)PATCH
:更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少,这里就不举例子了。
-
method
:兼容HTTP的方法名 -
params
:根据HTTP参数的存在、缺省或值对请求进行过滤 -
header
:根据HTTP Header的存在、缺省或值对请求进行过滤 -
consume
:设定在HTTP请求正文中允许使用的媒体类型 -
product
:在HTTP响应体中允许使用的媒体类型
示例:
@RequestMapping("/users")
public List getAllUsers() {
return userRepository.findAll();
}
@GetMapping
@GetMapping
注解用于处理HTTP GET请求,并将请求映射到具体的处理方法中。具体来说,@GetMapping是一个组合注解,它相当于是@RequestMapping(method=RequestMethod.GET)
的快捷方式。
下面是@GetMapping
的一个使用示例:
@GetMapping("/users") 功能相同
@RequestMapping(value="/users",method=RequestMethod.GET)
//value={} 可添加多个地址 多个地址都指向这一个方法
@GetMapping(value = {"/users", "/apis/users"})
public List getAllUsers() {
return userRepository.findAll();
}
@PostMapping
@PostMapping
注解用于处理HTTP POST请求,并将请求映射到具体的处理方法中。@PostMapping与@GetMapping一样,也是一个组合注解,它相当于是@RequestMapping(method=HttpMethod.POST)
的快捷方式。
下面是使用@PostMapping
的一个示例:
@PostMapping("users") 功能相同
@RequestMapping(value="/users",method=RequestMethod.POST)
//value={} 可添加多个地址 多个地址都指向这一个方法
@PostMapping("/users")
public List createUser(@RequestBody UserCreateRequest userCreateRequest) {
return userRespository.save(user);
}
图片
@PutMapping
@PutMapping
注解用于处理HTTP PUT请求,并将请求映射到具体的处理方法中,@PutMapping是一个组合注解,相当于是@RequestMapping(method=HttpMethod.PUT)
的快捷方式。
下面是使用@PutMapping
的一个示例:
@PutMapping("/users/{userId}") 功能相同
@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
//value={} 可添加多个地址 多个地址都指向这一个方法
@PutMapping("/users/{userId}")
public List updateUser(@PathVariable(value = "userId") Long userId,@RequestBody Map map) {
......
}
@DeleteMapping
@DeleteMapping
注解用于处理HTTP DELETE请求,并将请求映射到删除方法中。@DeleteMapping是一个组合注解,它相当于是@RequestMapping(method=HttpMethod.DELETE)
的快捷方式。
下面是使用@DeleteMapping
的一个示例:
@DeleteMapping("/users/{userId}")功能相同
@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)
//value={} 可添加多个地址 多个地址都指向这一个方法
@DeleteMapping("/users/{userId}")
public boolean deleteUser(@PathVariable(value = "userId") Long userId){
......
}
@PatchMapping
@PatchMapping
注解用于处理HTTP PATCH请求,并将请求映射到对应的处理方法中。@PatchMapping相当于是@RequestMapping(method=HttpMethod.PATCH)
的快捷方式。
下面是一个简单的示例:
@PatchMapping("/profile")
public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
studentRepository.updateDetail(studentUpdateRequest);
return ResponseEntity.ok().build();
}
7. 前后端传值
@PathVariable
@PathVariable
注解是将方法中的参数绑定到请求URI中的模板变量上。可以通过@RequestMapping
注解来指定URI的模板变量,然后使用@PathVariable
注解将方法中的参数绑定到模板变量上。
特别地,@PathVariable
注解允许我们使用value或name属性来给参数取一个别名。下面是使用此注解的一个示例:
@GetMapping(value = {"/getSysParameterData/{codeOrName}/{sys}", "/getSysParameterData/{codeOrName}"})
public List getSysParameterData(@PathVariable String codeOrName, @PathVariable(value = "sys", required = false) String sys) {
return sysParameterService.getSysParameterData(codeOrName, sys);
}
请求地址:/getSysParameterData/1/2、/getSysParameterData/1
模板变量名需要使用{ }
进行包裹,如果方法的参数名与URI模板变量名一致,则在@PathVariable
中就可以省略别名的定义。
提示:如果参数是一个非必须的,可选的项,则可以在@PathVariable
中设置require = false
@RequestParam
@RequestParam
注解用于将方法的参数与Web请求的传递的参数进行绑定。使用@RequestParam
可以轻松的访问HTTP请求参数的值。
- name :字段名称
- required:默认为true ,false 时改参数可为空
示例:
@GetMapping("/getSysParameterData}")
public List getSysParameterData(@RequestParam String codeOrName,@RequestParam(name = "sys", required =false) String sys) {
return sysParameterService.getSysParameterData(codeOrName, sys);
}
请求地址:/getSysParameterData?codeOrName=1&sys=2、/getSysParameterData?codeOrName=1
@RequestBody
@RequestBody在处理请求方法的参数列表中使用,它可以将请求主体中的参数绑定到一个对象中,请求主体参数是通过HttpMessageConverter
传递的,根据请求主体中的参数名与对象的属性名进行匹配并绑定值。
此外,还可以通过@Valid注解对请求主体中的参数进行校验。
下面是一个使用@RequestBody
的示例:
@PostMapping("/sign-up")
public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) {
userService.save(userRegisterRequest);
return ResponseEntity.ok().build();
}
@ResponseBody
@ResponseBody
会自动将控制器中方法的返回值写入到HTTP响应中。特别的,@ResponseBody
注解只能用在被@Controller
注解标记的类中。
如果在被@RestController
标记的类中,则方法不需要使用@ResponseBody
注解进行标注。
@RestController
相当于是@Controller
和@ResponseBody
的组合注解。
下面是使用该注解的一个示例
@ResponseBody
@GetMapping("/users")
public List getAllUsers() {
return userRepository.findAll();
}
8.事务处理
@Transactional
在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作,可用到@Transactional注解
示例:
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional()
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return company;
}
...
}
事务详细内容可参考:Spring事务介绍