本文打算介绍几个不太容易说出其区别,或者用处的 Spring 注解,比方 @Component
与 @Bean
的比拟,@ControllerAdvice
是如何解决自定义异样的等等。
Spring 中的一些注解
1. @Component 和 @Bean 的区别是什么?
- 作用对象不同:
@Component
注解作用于类,而@Bean
注解作用于办法、 @Component
通常是通过门路扫描来主动侦测以及主动拆卸到 Spring 容器中(咱们能够应用@ComponentScan
注解定义要扫描的门路从中找出标识了须要拆卸的类主动拆卸到 Spring 的 bean 容器中)。@Bean
注解通常是咱们在标有该注解的办法中定义产生这个 bean,@Bean
通知了 Spring 这是某个类的实例,当咱们须要用它的时候还给我。@Bean
注解比@Component
注解的自定义性更强,而且很多中央咱们只能通过@Bean
注解来注册 bean。比方当咱们援用第三方库中的类须要拆卸到 Spring 容器时,只能通过@Bean
来实现。
@Bean
注解应用示例:
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {return new TransferServiceImpl();
}
}
@Component 注解应用示例:
@Component
public class ServiceImpl implements AService {....}
上面这个例子是通过 @Component 无奈实现的:
@Bean
public OneService getService(status) {case (status) {
when 1:
return new serviceImpl1();
when 2:
return new serviceImpl2();
when 3:
return new serviceImpl3();}
}
2. Autowire 和 @Resource 的区别
@Autowire
和@Resource
都能够用来拆卸 bean,都能够用于字段或 setter 办法。Spring Boot 学习笔记分享给你。@Autowire
默认按类型拆卸,默认状况下必须要求依赖对象必须存在,如果要容许 null 值,能够设置它的 required 属性为 false。@Resource
默认按名称拆卸,当找不到与名称匹配的 bean 时才依照类型进行拆卸。名称能够通过 name 属性指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名,当注解写在 setter 办法上时,默认取属性名进行拆卸。
留神:如果 name 属性一旦指定,就只会依照名称进行拆卸。
@Autowire
和 @Qualifier
配合应用成果和 @Resource
一样:
@Autowired(required = false) @Qualifier("example")
private Example example;
@Resource(name = "example")
private Example example;
@Resource
拆卸程序
- 如果同时指定 name 和 type,则从容器中查找惟一匹配的 bean 拆卸,找不到则抛出异样;
- 如果指定 name 属性,则从容器中查找名称匹配的 bean 拆卸,找不到则抛出异样;
- 如果指定 type 属性,则从容器中查找类型惟一匹配的 bean 拆卸,找不到或者找到多个抛出异样;
- 如果不指定,则主动依照 byName 形式拆卸,如果没有匹配,则回退一个原始类型进行匹配,如果匹配则主动拆卸。
3. 将一个类申明为 Spring 的 bean 的注解有哪些?
@Component
:通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不晓得属于哪个层,能够应用@Component
注解标注。@Repository
:对应长久层即 Dao 层,次要用于数据库相干操作。@Service
:对应服务层,次要设计一些简单的逻辑,须要用到 Dao 层。@Controller
:对应 Spring MVC 管制层,次要用来承受用户申请并调用 Service 层返回数据给前端页面。@Configuration
:申明该类为一个配置类,能够在此类中申明一个或多个@Bean
办法。
4. @Configuration:配置类注解
@Configuration
表明在一个类里能够申明一个或多个 @Bean
办法,并且能够由 Spring 容器解决,以便在运行时为这些 bean 生成 bean 定义和服务申请,例如:
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {// instantiate, configure and return bean ...}
}
咱们能够通过 AnnotationConfigApplicationContext 来注册 @Configuration
类:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...
另外也能够通过组件扫描 (component scanning) 来加载,@Configuration
应用 @Component
进行原注解,因而 @Configuration
类也能够被组件扫描到(特地是应用 XML 的 元素)。@Configuration
类不仅能够应用组件扫描进行疏导,还能够应用 @ComponentScan
注解自行配置组件扫描:
@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {// various @Bean definitions ...}
应用 @Configuration 的束缚:
- 配置类必须以类的形式提供(比方不能是由工厂办法返回的实例)。
- 配置类必须是非 final 的。
- 配置类必须是非本地的(即可能不在办法中申明),native 标注的办法。
- 任何嵌套的配置类必须申明为 static。
- @Bean 办法可能不会反过来创立更多的配置类。
除了独自应用 @Configuration
注解,咱们还能够联合一些内部的 bean 或者注解独特应用,比方 Environment API
,@PropertySource
,@Value
,@Profile
等等许多,这里就不做具体介绍了,更多的用法能够参看 Spring @Configuration 的相干文档。
举荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks…
5. @ControllerAdvice:解决全局异样利器
在 Spring 3.2 中,新增了 @ControllerAdvice
、@RestControllerAdvice
、@RestController
注解,能够用于定义 @ExceptionHandler
、@InitBinder
、@ModelAttribute
,并利用到所有 @RequestMapping
、@PostMapping
、@GetMapping
等这些 Controller 层的注解中。
默认状况下,@ControllerAdvice
中的办法利用于全局所有的 Controller。而应用选择器 annotations()
,basePackageClasses()
和 basePackages()
(或其别名 value())来定义更小范畴的指标 Controller 子集。Spring Boot 学习笔记分享给你。
如果申明了多个选择器,则利用 OR 逻辑,这意味着所选的控制器应匹配至多一个选择器。请留神,选择器查看是在运行时执行的,因而增加许多选择器可能会对性能产生负面影响并减少复杂性。
@ControllerAdvice
咱们最常应用的是联合 @ExceptionHandler
用于全局异样的解决。能够联合以下例子,咱们能够捕捉自定义的异样进行解决,并且能够自定义状态码返回:
@ControllerAdvice("com.developlee.errorhandle")
public class MyExceptionHandler {
/**
* 捕捉 CustomException
* @param e
* @return json 格局类型
*/
@ResponseBody
@ExceptionHandler({CustomException.class}) // 指定拦挡异样的类型
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 自定义浏览器返回状态码
public Map>String, Object< customExceptionHandler(CustomException e) {Map<String, Object> map = new HashMap<>();
map.put("code", e.getCode());
map.put("msg", e.getMsg());
return map;
}
}
更多信息能够参看 Spring @ControllerAdvice 的官网文档。举荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks…
6. @Component, @Repository, @Service 的区别
@Component
是一个通用的 Spring 容器治理的单例 bean 组件。而 @Repository
, @Service
, @Controller
就是针对不同的应用场景所采取的特定功能化的注解组件。
因而,当你的一个类被 @Component 所注解,那么就意味着同样能够用@Repository
, @Service
, @Controller
来代替它,同时这些注解会具备有更多的性能,而且性能各异。
最初,如果你不晓得要在我的项目的业务层采纳 @Service
还是 @Component
注解。那么,@Service
是一个更好的抉择。
总结
以上简略介绍了几种 Spring 中的几个注解及代码示例,就我集体而言,均是平时用到且不容易了解的几个,或者容易疏忽的几个。当然,这篇文章并没有齐全介绍完,在今后还会持续补充欠缺。