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

news2024/11/15 17:43:31

目录

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 {

    @Autowired
    IUserDao userDao;
    @Override
    public void getUser() {
        userDao.getUser();
    }
}


//配置类SpringConfig
@Configuration
public class SpringConfig {

    @Bean  //使用@Bean配置UserService成为bean
    public IUserService userService(){
        IUserDao userDao = UserDao();
        UserService userService = new UserService();
        return userService;
    }

    @Bean  //使用@Bean配置UserDao成为bean
    public IUserDao UserDao(){
        return new UserDao();
    }
}


//测试类C3IocApplicationTests
@SpringBootTest
class C3IocApplicationTests {
    @Autowired
    IUserService userService;

    @Test
    void 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 {
    @Override
    public 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 {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        //创建BeanDefinition,只有这个类的BeanDefinition存在了,才能根据这个BeanDefinition去创建类的bean对象
        RootBeanDefinition definition = new RootBeanDefinition();
        //把要创建bean的类的完整限定名传递给BeanDefinition
        definition.setBeanClassName("com.lt.ioc.service.UserService");
        //注册这个BeanDefinition
        registry.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方法返回的对象(狸猫换太子)
    @Override
    public Object getObject() throws Exception {//(这里getObject方法中返回的对象就是UserService)
        return new UserService();
    }

    @Override
    public 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接口的一个类,他是一个特殊的bean
        System.out.println(ioc.getBean("orderService"));//通过OrderService中重写了的getObject()方法来获取UserService的bean
        System.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.coloradmin.cn/o/1568497.html

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

相关文章

Linux简单介绍

Linux简单介绍 编译器VMware虚拟机Ubuntu——LinuxOS为什么使用LinuxOS&#xff1f; 目录结构Windows目录结构Linux操作系统home是不是家目录&#xff1f; Linux常用命令终端命令行提示符与权限切换命令tab 作用&#xff1a;自动补全上下箭头pwd命令ls命令mkdir命令touch命令rm…

C++实现vector

目录 前言 1.成员变量 2.成员函数 2.1构造函数 2.2析构函数 2.3begin,end 2.4获取size和capacity 2.5函数重载【】 2.6扩容reserve 2.7resize 2.8insert 2.9删除 2.10尾插、尾删 3.0拷贝构造函数 3.1赋值运算符重载 前言 自主实现C中vector大部分的功能可以使我们更好的理解并使…

flink源码编译-job提交

1、启动standalone集群的taskmanager standalone集群中的taskmanager启动类为 TaskManagerRunner 2 打开master启动类 通过 ctrln快捷键&#xff0c;找到、并打开类&#xff1a; org.apache.flink.runtime.taskexecutor.TaskManagerRunner 3 修改运⾏配置 基本完全按照mas…

高等数学基础篇之导数与微分的运算法则

导数与微分&#xff1a; 一、导数基本公式 二、微分基本公式 三、导数运算法则 四、微分运算法则 一、导数基本公式 二、微分基本公式 三、导数运算法则 四、微分运算法则 有理运算法则 设f(x), g(x)在x处可导&#xff0c;则&#xff1a; 复合函数运算法则 设 yf(u), ug…

【JavaScript】函数 ① ( 函数引入 | 函数声明 | 函数调用 )

文章目录 一、JavaScript 函数1、函数引入2、函数声明3、函数调用4、代码示例 - 函数声明调用 一、JavaScript 函数 1、函数引入 JavaScript 代码编写时 , 会遇到 定义 大量相同或相似代码的 场景 , 这些代码可能需要重复使用 , 这种情况下就需要 将 这些代码 定义在 函数 中 ;…

解决Vue中仓库持久化的问题,不借助插件用原生JS实现仓库持久化。了解仓库的插件机制、监听的时机

1、演示 前言&#xff1a;目前Vue有两种仓库&#xff0c;一种是Vuex&#xff0c;一种是Pinia&#xff0c;懂得都懂&#xff0c;这里就不详细介绍这两者的区别了 2、什么是持久化 仓库里面的数据是需要跨越页面周期的&#xff0c;当页面刷新之后数据还在&#xff0c;在默认情况下…

NoSQL之Redis

目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 &#xff08;3&#xff09;对事物性的支持不同 …

日常生活中使用的 4 个核心开发工具

长话短说 本文列出了 2024 年我作为开发人员在日常生活中最常用的 4 个工具。✅ 这些工具旨在提高您的编辑技能、终端导航、笔记以及在应用程序容器化之外使用 Docker。另外&#xff0c;最后我还给大家准备了一个小惊喜。 如果您没有使用本文中至少提到的 1-2 个工具&#xf…

银行数字化转型导师坚鹏:银行数字化转型必知的3大客户分析维度

银行数字化转型需要进行客户分析&#xff0c;如何进行客户分析呢&#xff1f;银行数字化转型导师坚鹏认为至少从客户需求分析、客户画像分析、客户购买行为分析3个维度进行客户分析。 1.客户需求分析 银行数字化转型需要了解客户需求&#xff0c;不同年龄段的客户有不同的需求…

医院云HIS系统源码,二级医院、专科医院his系统源码,经扩展后能够应用于医联体/医共体

基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云LIS&#xff0…

echarts 地图 自己圈地图 乡镇街道

这个是方式是我实在不愿意做的&#xff01; 如果有现成的最好&#xff0c;没有办法的情况下再用这个东西。 今天公司有一个项目&#xff0c;地方划分了一块区域&#xff0c;但是国家没有审核&#xff0c;但是项目里面用到了一个地图展示数据&#xff01;然后就需要我们自己把…

vulhub中Apache Solr 远程命令执行漏洞复现(CVE-2019-0193)

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发&#xff0c;主要基于 HTTP 和 Apache Lucene 实现。此次漏洞出现在Apache Solr的DataImportHandler&#xff0c;该模块是一个可选但常用的模块&#xff0c;用于从数据库和其他源中提取数据。它具有一个功能&#…

Tailscale:随时随地远程和使用服务器

文章目录 Tailscale是什么&#xff1f;Tailscale能做什么&#xff1f;1、传输文件2、远程开发3、代理 Tailscale怎么用&#xff1f;Windows下安装OpenSSH在线安装离线安装连接SSH服务器 Reference相关阅读 彩蛋&#xff1a;Pycharm远程连接服务器并运行代码 Tailscale是什么&am…

10 年跟踪 Hacker News 招聘贴,解读科技行业变迁

Hackers News (HN) 是国外程序员最喜欢逛的论坛。能登上首页的帖子类似于上了新浪微博。因为其巨大的程序员访问量&#xff0c;因此也成为了公司招聘的渠道。久而久之 HN 招聘帖还形成了专门的标题格式 Ask HN: Who is hiring? 正好有人通过 Ask HN 来分析技术趋势&#xff0c…

如何(关闭)断开 Websocket 连接:简单易懂的实现指南

WebSocket 协议提供了一条用于 Web 应用程序中双向通讯的高效通道&#xff0c;让服务器能够实时地向客户端发送信息&#xff0c;而无需客户端每次都发起请求。本文旨在探讨有关结束 WebSocket 连接的适当时机&#xff0c;内容包括协议的基础知识、如何结束连接、一些使用场景&a…

本地运行github上下载的项目--接Git入门篇

1.了解项目 这是一个基于Spring Boot 和 Mybatis Plus 构建的Java项目&#xff0c;很经典的外卖项目&#xff0c;参考b站的黑马瑞吉外卖。 2.构建项目 SpringBoot项目&#xff0c;首先下载一些常见的项目要求的组件。然后配置如下&#xff1a; 看README&#xff0c;在阅读该…

深入理解计算机系统 家庭作业 2.80

/* 网上很多都没说清楚到底出题人是什么用意,用意就是既要又要,既要不溢出,又要不丢失精度.所以就分开处理,在丢失之前把丢失的部分保存下来,然后两部分算好再相加. 可以先看一下我的2.79题 用的是先乘后除 会溢出 符合题意 2.80要求的是先除后成 不会溢出 但会丢失精度 核…

1.3 操作系统的运行机制、中断与异常、系统调用

一、操作系统的运行机制 知识框图&#xff1a; &#xff08;一&#xff09;程序 内核程序&#xff1a;内核程序是操作系统的核心部分&#xff0c;需要在内核模式下运行&#xff0c;负责管理计算机的硬件资源&#xff0c;如处理器、内存、存储设备和输入输出设备。内核程序还负…

自动驾驶中各种坐标系辨析

坐标系辨析 0. 地球椭圆体1. 大地坐标系2. eci地心惯性坐标系3. 地心地固坐标系(ECEF坐标系&#xff0c;E系)4. 站心坐标系(ENU坐标系)5. UTM坐标系6. LTM坐标系7. IMU坐标系8. 代码部分8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标8.2 LLA坐标转…

Coursera上Learning Linux for LFCA Certification专项课程01:Linux Fundamentals 学习笔记

Linux Fundamentals Course Certificate 本文是 Linux Fundamentals 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Linux FundamentalsWeek 01: Linux Operating SystemLearning Objectives Specialization OverviewHistory of LinuxQuiz: Hist…