【Spring】使用@Bean和@Import注解配置Bean,与Bean的实例化

目录

1、bean是什么

2、配置bean

2.1、使用@Bean注解配置Bean

2.2、使用@Import注解配置Bean

 3、实例化Bean

1、bean是什么

        在 Spring 中,Bean 是指由 Spring 容器管理的对象。Spring IOC 容器负责创建、配置和管理这些 Bean 对象的生命周期。Spring IOC 容器会管理应用程序中的组件,并通过依赖注入(DI)将它们组装在一起。Bean 是应用程序的核心构建块,它们通常代表应用程序中的各种对象,例如服务、数据访问对象(DAO)、控制器等。

        要在 Spring 中使用 Bean,通常需要在 Spring 配置文件(如 XML 文件)或使用注解(@Component)来声明 Bean,并告诉 Spring 容器如何创建和配置它们。一旦 Bean 被声明和配置好,Spring 容器将负责实例化它们,并在需要时将它们注入到其他 Bean 中。

        简单来说就是:在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。bean 是由Spring IoC 容器实例化、组装和管理的对象。

 

2、配置bean

        配置bean可以通过在 xml 文件中用 <bean class=""> 这个标签的方式来进行显式的声明,但是这种方式太麻烦了。

        所以现在都是通过 @component注解 来把类配置成bean,在类级别上使用 @Component 注解或其派生注解(@Service、@Repository、@Controller 等)就可以将一个类声明为 Bean

        这两种配置方式可以看这一篇:【Spring】分别基于XML、注解和配置类实现Spring的IOC(控制反转)-CSDN博客

这里主要是使用@Bean和@Import注解配置Bean

2.1、使用@Bean注解配置Bean

@Bean 特性:

一、是放在方法上面的

二、必须放在配置类里面

        @Bean方法调用另外一个@Bean方法,会从spring容器中去获取

三、@Bean可以干预bean的实例化过程的,而且jar包中的类如果要配置bean就需要用@Bean

四、在这个方法中声明的参数,spring也会帮我们自动注入进来

相关代码:

//接口IUserDao
public interface IUserDao {//执行查询用户void getUser();
}//接口IUserDao的实现类UserDao
public class UserDao implements IUserDao {@Override//执行查询用户public void getUser() {System.out.println("Holle Spring");}
}//接口IUserService
public interface IUserService {void getUser();
}//接口IUserService的实现类UserService
//@Service
public class UserService implements IUserService {@AutowiredIUserDao userDao;@Overridepublic void getUser() {userDao.getUser();}
}//配置类SpringConfig
@Configuration
public class SpringConfig {@Bean  //使用@Bean配置UserService成为beanpublic IUserService userService(){IUserDao userDao = UserDao();UserService userService = new UserService();return userService;}@Bean  //使用@Bean配置UserDao成为beanpublic IUserDao UserDao(){return new UserDao();}
}//测试类C3IocApplicationTests
@SpringBootTest
class C3IocApplicationTests {@AutowiredIUserService userService;@Testvoid contextLoads() {userService.getUser();}
}

2.2、使用@Import注解配置Bean

@lmport 特性:

一、@lmport必须写在类上面,不能用于方法等其他的上面

二、标记的类必须是一个bean,否则不会起作用

 @lmport的三种使用方式

(1)普通类:就是直接@lmport(UserService.class)普通类,就会把这个普通类注入spring

示例:

(2)lmportSelector :用于根据完整限定名字符串批量注入Bean

        a、定义一个类实现lmportSelector

        b、批量注册bean(通过实现selectlmports,返回bean的完整类路径字符串数组)

        c、然后在配置类上加上@lmport(实现lmportSelector.class)

示例:

 

其他代码和上面使用@Bean的例子是一样的,实现了 ImportSelector 接口的 MyImportSelector 类代码:

public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.lt.ioc.service.UserService","com.lt.ioc.dao.UserDao"};}
}

(3)ImportBeanDefinitionRegistrar

        定义一个类实现lmportBeanDefinitionRegistrar,然后在方法里根据beanDefinition注册bean

示例:和上面的 lmportSelector 用法一样,把实现了 ImportBeanDefinitionRegistrar 接口的类传递给@Import注解就可以

实现了 ImportBeanDefinitionRegistrar 接口的 MyImportBeanDefinitionRegistrar 类代码:

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {//创建BeanDefinition,只有这个类的BeanDefinition存在了,才能根据这个BeanDefinition去创建类的bean对象RootBeanDefinition definition = new RootBeanDefinition();//把要创建bean的类的完整限定名传递给BeanDefinitiondefinition.setBeanClassName("com.lt.ioc.service.UserService");//注册这个BeanDefinitionregistry.registerBeanDefinition("userService",definition);}
}

 3、实例化Bean

1、spring会默认使用无参构造器(无参构造函数)实例化

  • 有多个构造函数依然会调用无参构造函数
  • 如果只有一个有参构造函数,spring就会调用这个有参构造函数,并且把参数自动装配进来
  • 如果有参构造函数有个多个,并且没有无参构造函数,那就会报错,因为spring不知道该选哪一个构造函数,这时候对spring来说,他需要一个默认的无参构造函数

2、使用实例工厂方法实例化--@Bean

  • 可以自由的选择构造函数进行实例化

 

3、使用工厂Bean。实例化--FactoryBean

  • FactoryBean是一个接口
  • 需要有一个Bean,一旦这个Bean实现FaétoryBean就成为了特殊的Bean
  • 需要实现2个方法

        1)getObject() ---->当通过Bean实际名称获取到的就是getObject 返回的对象(伪装)

        2)getObjecType()---->想通过容器去获取对应(getObject 返回的对象)的类型,就需要返回getObject 返回的对象的类型

  • 可以自由的选择构造函数进行实例化

示例:

OrderService类是加了@Service注解并且实现了FactoryBean接口的一个类,代码:

@Service
public class OrderService implements FactoryBean {// 加了@Service注解并且实现了FactoryBean接口的OrderService变成了一个特殊的bean// 特殊: 就是根据bean(这里是OrderService)的名字实际上是获取getObject方法返回的对象(狸猫换太子)@Overridepublic Object getObject() throws Exception {//(这里getObject方法中返回的对象就是UserService)return new UserService();}@Overridepublic Class<?> getObjectType() {//想通过容器去获取对应(getObject 返回的对象)的类型,就需要返回getObject返回的对象的类型return UserService.class;}
}

获取容器,并分别通过FactoryBean接口中的两种方法从容器中获取UserService的bean和获取实现了FactoryBean接口的OrderService实际的Bean

//启动类C3IocApplication
@SpringBootApplication
public class IocApplication {public static void main(String[] args) {ConfigurableApplicationContext ioc = SpringApplication.run(IocApplication.class, args);//OrderService是加了@Service注解并且实现了FactoryBean接口的一个类,他是一个特殊的beanSystem.out.println(ioc.getBean("orderService"));//通过OrderService中重写了的getObject()方法来获取UserService的beanSystem.out.println(ioc.getBean(UserService.class));//通过OrderService中重写了的getObjectType()方法来获取UserService的bean//如果想获取FactoryBean实际的Bean可以 1.通过类型; 2.在beanName前加上&System.out.println(ioc.getBean(OrderService.class));System.out.println(ioc.getBean("&orderService"));}}

推荐: 

【Spring】分别基于XML、注解和配置类实现Spring的IOC(控制反转)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137237805?spm=1001.2014.3001.5501

 【java多线程】通过等待唤醒机制、局部变量、原子变量实现线程同步-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137122461?spm=1001.2014.3001.5501

【java多线程】通过等待唤醒机制、局部变量、原子变量实现线程同步-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137122461?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/790562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++混合项目,程序运行报错:未定义函数符号

参考 C/C项目混合编译 extern "C" 详解 《C Primer Plus》函数重载篇章 环境 系统&#xff1a;ubuntu20 编译器&#xff1a;gcc 问题 C 和 C 源码的混合项目&#xff0c;编译成功&#xff0c;但是程序运行报错找不到函数符号。 背景 项目中使用第三方的代码&a…

03.31_111期_C++_list特性和使用

利用想定义一个带头双向链表的迭代器 只能通过在 带头双向链表的类 中同一个命名空间中 再定义一个类 这个类规定 带头双向链表中迭代器的行为 下面的设计需要注意&#xff1a; 1. 定义的这个类需要写出构造函数&#xff0c; 1.1 构造函数…

边缘计算盒子与云计算:谁更适合您的业务需求?

边缘计算盒子和云计算&#xff0c;这两个概念听起来可能有点复杂&#xff0c;但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢&#xff1f;咱们来详细说说。 边缘计算盒子&#xff0c;就像是个小型的数据处理中心&#xff0c;放在离你业务现场比较近的地方。它…

Tensorflow2.0笔记 - 自定义Layer和Model实现CIFAR10数据集的训练

本笔记记录使用自定义Layer和Model来做CIFAR10数据集的训练。 CIFAR10数据集下载&#xff1a; https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 自定义的Layer和Model实现较为简单&#xff0c;参数量较少&#xff0c;并且没有卷积层和dropout等&#xff0c;最终准确率…

基于java+SpringBoot+Vue的图书个性化推荐系统的设计与实现

基于javaSpringBootVue的图书个性化推荐系统的设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis Vue工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 首页&#xff1a;展示图书信息、好书推荐、留言反馈等。 图书信息&#xff1a;用户可以查看图…

easyExcel 模版导出 中间数据纵向延伸,并且对指定列进行合并

想要达到的效果 引入maven引用 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version></dependency> 按照要求创建模版 备注 : 模板注意 用{} 来表示你要用的变量 如果本…

商务电子邮件: 在WorkPlace中高效且安全

高效和安全的沟通是任何组织成功的核心。在我们关于电子邮件类型的系列文章的第二期中&#xff0c;我们将重点关注商业电子邮件在促进无缝交互中的关键作用。当你身处重要的工作场环境时&#xff0c;本系列的每篇文章都提供了电子邮件的不同维度的视角。 “2024年&#xff0c;全…

01 使用ArcGIS生成节点路径

目录 1 测试数据准备 1.1 创建空的GDB文件及数据集 1.2 创建道路图层 1.3 绘制路网

计算机视觉之三维重建(6)---多视图几何(上)

文章目录 一、运动恢复结构问题&#xff08;SfM&#xff09;二、欧式结构恢复2.1 概述2.2 求解2.3 欧式结构恢复歧义 三、仿射结构恢复3.1 概述3.2 因式分解法3.3 总结3.4 仿射结构恢复歧义 一、运动恢复结构问题&#xff08;SfM&#xff09; 1. 运动恢复结构问题&#xff1a;通…

enqueue:oracle锁机制

实现锁的方式就是排队咯&#xff0c;那么排队就是有enqueue这么个结构来管理 管理锁的结构叫队列&#xff0c;即enqueue 所有和enqueue相关的函数都叫KSQ-- kernal service enqueue lock是从应用层面看到的锁&#xff0c;enqueue是oracle内部管理锁的一个结构。 可以用v$lock_…

python将visio转换为 PDF 文件

参考链接&#xff1a;在 Python 中將 Visio 轉換為 PDF | Python Visio 到 PDF 庫 (aspose.com) 下载软件包&#xff1a; pip install aspose-diagram-python 读取文件&#xff0c;保存为PDF # 此代碼示例演示如何使用 PDF 保存選項將 Visio 轉換為 PDF import aspose.dia…

基于单片机的超声波测距仪设计_kaic

摘 要 如今社会持续深化转型&#xff0c;在人工智能领域&#xff0c;传感器采集外部数据&#xff0c;经过处理器对数 据运算和处理&#xff0c;从而实现相应的功能。比如自动驾驶技术中&#xff0c;超声波传感器应用广泛&#xff0c; 超声波是一种频率在 20khz 以上的声波&…

HTML优化SEO的实用技巧

在网站开发中&#xff0c;除了关注设计和用户体验&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;也是提升网站流量和可见度的关键。合理的HTML结构和元素运用能够帮助搜索引擎更好地理解页面内容&#xff0c;从而提高搜索排名。以下是一些基于HTML的SEO优化技巧&#xf…

OpenHarmony实战:小型系统移植概述

驱动主要包含两部分&#xff0c;平台驱动和器件驱动。平台驱动主要包括通常在SOC内的GPIO、I2C、SPI等&#xff1b;器件驱动则主要包含通常在SOC外的器件&#xff0c;如 LCD、TP、WLAN等 图1 OpenHarmony 驱动分类 HDF驱动被设计为可以跨OS使用的驱动程序&#xff0c;HDF驱动框…

【WebKit架构讲解】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Nginx从安装到高可用实用教程!

一、Nginx安装 1、去官网http://nginx.org/下载对应的nginx包&#xff0c;推荐使用稳定版本 2、上传nginx到linux系统 3、安装依赖环境 (1)安装gcc环境 yum install gcc-c(2)安装PCRE库&#xff0c;用于解析正则表达式 yum install -y pcre pcre-devel(3)zlib压缩和解压缩…

java面试题(3)|解释 null 和 “null“ 之间的区别,并举例说明它们在编程中的使用场景

null 和 "null" 之间的区别主要在于语义和数据类型上&#xff1a; null 是一个特殊的值&#xff0c;通常用于表示缺少有效值或未定义的变量。在许多编程语言中&#xff0c;null是一个关键字&#xff0c;表示空值。例如&#xff0c;在Java中&#xff0c;当一个对象尚…

解决el-table设置固定高度后,展示不同列时表格高度变小bug

解决el-table设置固定高度后&#xff0c;展示不同列时表格高度变小bug 1、需求分析2、解决方案 1、需求分析 在el-table使用过程中&#xff0c;选择多个参数展示更多列时会出现高度变小问题究其原因可知是el-table列动态发生变化后&#xff0c;el-table__body-wrapper的高度变…

sqlite在非主键创建一个自增字段

sqlite 自增比较奇葩&#xff0c;自增字段必须建在主键上&#xff0c;但主键很重要。不是每种情况都是给自增去做。比如要实现replace into 时&#xff0c; 要主键作为更新标识。用自增很难实现。 开工&#xff1a; 1、建立一个主表&#xff0c;主表的ID是自增ID&#xff0c;…

CNAS软件测试公司有什么好处?如何选择靠谱的软件测试公司?

CNAS认可是中国合格评定国家认可委员会的英文缩写&#xff0c;由国家认证认可监督管理委员会批准设立并授权的国家认可机构&#xff0c;统一负责对认证机构、实验室和检验机构等相关机构的认可工作。 在软件测试行业&#xff0c;CNAS认可具有重要意义。它标志着一个软件测试公…