Spring 注解 @bean 和 @component 的区别, 你知道吗?
本文打算介绍几个不太容易说出其区别,或者用途的 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
注解使用示例:
@Configurationpublic class AppConfig { @Beanpublic TransferService transferService() {return new TransferServiceImpl(); }}
@Component 注解使用示例:
@Componentpublic class ServiceImpl implements AService { ....}
下面这个例子是通过 @Component 无法实现的:
@Beanpublic 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方法。@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 定义和服务请求,例如:
@Configurationpublic class AppConfig { @Beanpublic 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 的相关文档 。
5. @ControllerAdvice :处理全局异常利器
在 Spring 3.2 中,新增了 @ControllerAdvice
、@RestControllerAdvice
、@RestController
注解,可以用于定义 @ExceptionHandler
、@InitBinder
、@ModelAttribute
,并应用到所有 @RequestMapping
、@PostMapping
、@GetMapping
等这些 Controller 层的注解中。
默认情况下,@ControllerAdvice
中的方法应用于全局所有的 Controller。而使用选择器 annotations()
,basePackageClasses()
和 basePackages()
(或其别名value())来定义更小范围的目标 Controller 子集。如果声明了多个选择器,则应用 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 的官方文档。
6. @Component, @Repository, @Service 的区别
@Component
是一个通用的Spring容器管理的单例bean组件。而@Repository
, @Service
, @Controller
就是针对不同的使用场景所采取的特定功能化的注解组件。
因此,当你的一个类被@Component所注解,那么就意味着同样可以用@Repository
, @Service
, @Controller
来替代它,同时这些注解会具备有更多的功能,而且功能各异。
最后,如果你不知道要在项目的业务层采用@Service
还是@Component
注解。那么,@Service
是一个更好的选择。
总结
以上简单介绍了几种 Spring 中的几个注解及代码示例,就我个人而言,均是平时用到且不容易理解的几个,或者容易忽略的几个。当然,这篇文章并没有完全介绍完,在今后还会继续补充完善。
Spring 注解 @bean 和 @component 的区别, 你知道吗?相关推荐
- 一次性讲清 Spring 常用注解 @Bean 、 @Component 、@Autowire、@Resource 的区别, 你知道吗?
本文打算介绍几个不太容易说出其区别,或者用途的 Spring 注解,比如 @Component 与 @Bean 的比较,@ControllerAdvice 是如何处理自定义异常的等等. Spring ...
- Spring 注解比较,@Bean 和 @Component的区别
点击下方"IT牧场",选择"设为星标" 本文打算介绍几个不太容易说出其区别,或者用途的 Spring 注解,比如 @Component 与 @Bean 的比较, ...
- spring注解--@Bean
@Configuration public class KnightConfig {@Beanpublic Knight knight(){return new BraveKnight(quest ( ...
- @Bean 与@Component的区别
https://blog.csdn.net/wh1236666/article/details/100541313
- Spring注解@Component、@Repository、@Service、@Controller,@Autowired、@Resource用法
一.Spring定义bean,@Component.@Repository.@Service 和 @Controller Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥 ...
- 面试官:讲讲Spring框架Bean的加载过程
spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...
- Spring注解的使用步骤,@Component注解创建的对象名称,常用注解Component、Repository、Service以及Controller的区别
1. 注解的使用 1.1 pom.xml文件加入spring-context依赖,间接加入了spring-aop依赖,有aop依赖才能使用注解 1.2 在spring配置文件中加入组件扫描器标签< ...
- Spring的@bean注解
1.Spring注解分类 从广义上Spring注解可以分为两类: 一类注解是用于注册Bean 假如IOC容器就是一间空屋子,首先这间空屋子啥都没有,我们要吃大餐,我们就要从外部搬运食材和餐具进来.这里 ...
- Spring注解定义 bean 的12种方法
前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...
最新文章
- python sys模块 输入输出 错误流
- 生活在AI的世界是种什么体验?
- 网络运维基础之IP地址学习
- Spring框架你敢写精通,面试官就敢问@Autowired注解的实现原理
- OpenCASCADE绘制测试线束:拓扑命令之3D模型周期性
- SpringBoot-@RequestParam
- 世纪华通发布重组盛大游戏草案 承诺未来三年实现利润近76亿
- 乐视云计算基于OpenStack的IaaS实践
- 【数据结构与算法】实践 构造病种树结构
- Bootstrap按钮组嵌套
- 【USACO 1.3】Ski Course Design
- 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)
- dev多行注释_Shell 实现多行注释的几种常用方法
- Xcode打包ipa基本步骤
- 如何查看Linux虚拟机ip地址
- HD2500显卡驱动linux,英特尔HD Graphics 4000/2500 集成显卡驱动
- 自动生成文章摘要[JavaScript 版本]
- 手机通讯录被删除后怎么恢复
- SSO单点登录 1实现机制 ▪ 系统共享 ▪ 信息识别 2WEB-SSO 3其他含义 4技术应用 ▪ 技术实现[百度百科]
- 豆粕、白糖期货涨跌幅的可视化分析
热门文章
- Cell子刊:人类微生物组参考基因集中的单体基因
- 宏基因组-微生物组文章目录索引(1803)
- 宏基因组实战8. 分箱宏基因组binning, MqaxBin, MetaBin, VizBin
- pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动标准差(rolling std)、例如,计算某公司的多个店铺每N天(5天)的滚动销售额标准差
- python使用sklearn中的make_blobs函数生成聚类(clustering)分析需要的仿真数据、matplotlib可视化生成的仿真数据
- R语言使用str_split函数和str_split_fixed函数将字符串分割(分裂、split)成几个部分:str_split函数使用指定的字符或者字符串分割字符串、str_split_fixed
- Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战
- 特征工程(feature engineering)是什么?特征工程(feature engineering)包含哪些方面?
- Comprehensive anticancer drug response prediction based on a simple cell line drug complex network m
- linux关机 hibernate,Linux关机命令