• 【Spring】——1、使用@Configuration和@Bean给容器中注册组件


    在这里插入图片描述

    📫作者简介:zhz小白
    公众号:小白的Java进阶之路
    专业技能:
    1、Java基础,并精通多线程的开发,熟悉JVM原理
    2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
    3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
    4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
    5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
    6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
    7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
    8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
    9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
    10、熟悉常⽤设计模式,并运⽤于实践⼯作中
    11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
    12、了解K8s,Jekins,GitLab
    13、了解VUE,GO
    14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等

    本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
    领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
    🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

    Spring IOC和DI

    在Spring容器的底层,最重要的功能就是IOC和DI,也就是控制反转和依赖注入。
    在这里插入图片描述
    DI和IOC它俩之间的关系是DI不能单独存在,DI需要在IOC的基础上来完成。
    在Spring内部,所有的组件都会放到IOC容器中,组件之间的关系通过IOC容器来自动装配,也就是我们所说的依赖注入。接下来,我们就使用注解的方式来完成容器中组件的注册、管理及依赖、注入等功能。

    在介绍使用注解完成容器中组件的注册、管理及依赖、注入等功能之前,我们先来看看使用XML配置文件是如何注入bean的。

    通过XML配置文件注入JavaBean

    首先,新建一个maven项目,例如spring-annotation-learn,注意其打包方式是jar。
    在maven依赖中添加:

    <dependencies>
      <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
        <version>5.3.23version>
      dependency>
      <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.18.24version>
      dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    接着,在工程的com.zhz.bean包下创建一个Person类,作为测试的JavaBean,代码如下所示。

    package com.zhz.bean;
    
    import lombok.*;
    
    /**
     * @author zhouhengzhe
     * @description: 实体类
     * @date 2022/11/4 10:12
     * @since v1
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @ToString
    public class Person {
        private String name;
        private Integer age;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    紧接着,在工程的src/main/resources目录下创建Spring的配置文件,例如beans.xml,通过该配置文件将Person类注入到Spring的IOC容器中,该配置文件中的内容如下所示。(我这里一次性全部导入,后面就不需要导入了)

    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0modelVersion>
    
      <groupId>org.examplegroupId>
      <artifactId>spring-annotation-learnartifactId>
      <version>1.0-SNAPSHOTversion>
    
      <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
        <spring.version>5.3.23spring.version>
      properties>
      <dependencies>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-contextartifactId>
          <version>${spring.version}version>
        dependency>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-coreartifactId>
          <version>${spring.version}version>
        dependency>
        <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
          <version>1.18.24version>
        dependency>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-beansartifactId>
          <version>${spring.version}version>
        dependency>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-aopartifactId>
          <version>${spring.version}version>
        dependency>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-aspectsartifactId>
          <version>${spring.version}version>
        dependency>
        
        <dependency>
          <groupId>org.aspectjgroupId>
          <artifactId>aspectjrtartifactId>
          <version>1.9.9.1version>
        dependency>
        
        
        
        
        
        
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-txartifactId>
          <version>${spring.version}version>
        dependency>
        
                <dependency>
                    <groupId>org.springframeworkgroupId>
                    <artifactId>spring-webartifactId>
                    <version>${spring.version}version>
                dependency>
        
                <dependency>
                    <groupId>org.springframeworkgroupId>
                    <artifactId>spring-webmvcartifactId>
                    <version>${spring.version}version>
                dependency>
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-testartifactId>
          <version>${spring.version}version>
        dependency>
        <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.13.2version>
          <scope>testscope>
        dependency>
          <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>transmittable-thread-localartifactId>
                <version>2.14.2version>
            dependency>
      dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    至此,我们使用XML配置文件的方式注入JavaBean就完成了。
    接下来,我们在工程的com.zhz包下创建一个MainTest类来进行测试,该类的代码如下所示。

    package com.zhz;
    
    import com.zhz.bean.Person;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author zhouhengzhe
     * @description: 测试类
     * @date 2022/11/4 10:15
     * @since v1
     */
    public class MainTest {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
            Person person = (Person) applicationContext.getBean("person");
            System.out.println(person);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    通过注解注入JavaBean

    通过XML配置文件的方式,我们可以将JavaBean注入到Spring的IOC容器中。那使用注解又该如何实现呢?别急,其实使用注解比使用XML配置文件要简单的多,我们在项目的com.meimeixia.config包下创建一个MainConfig类,并在该类上添加@Configuration注解来标注该类是一个Spring的配置类,也就是告诉Spring它是一个配置类,最后通过**@Bean注解将Person类注入到Spring的IOC**容器中。

    package com.zhz.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.zhz.bean.Person;
    /**
     * 以前配置文件的方式被替换成了配置类,即配置类==配置文件
     * @author zhz
     *
     */
    // 这个配置类也是一个组件 
    @Configuration // 告诉Spring这是一个配置类
    public class MainConfig {
    
    	// @Bean注解是给IOC容器中注册一个bean,类型自然就是返回值的类型,id默认是用方法名作为id
    	@Bean
    	public Person person() {
    		return new Person("zhz", 20);
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    没错,通过MainConfig类我们就能够将Person类注入到Spring的IOC容器中,是不是很Nice啊!!主要是我们在类上加上@Configuration注解,并在方法上加上@Bean注解,就能够将方法中创建的JavaBean注入到Spring的IOC容器中。

    然后,我们修改MainTest类中的main方法,以测试通过注解注入的Person类,如下所示。

    package com.zhz;
    
    import com.zhz.bean.Person;
    import com.zhz.config.MainConfig;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author zhouhengzhe
     * @description: 测试类
     * @date 2022/11/4 10:15
     * @since v1
     */
    public class MainTest {
        public static void main(String[] args) {
    //        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
    //        Person person = (Person) applicationContext.getBean("person");
    //        System.out.println(person);
            ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
            Person person = annotationConfigApplicationContext.getBean(Person.class);
            System.out.println(person);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    到这里,我们已经明确了,通过XML配置文件和注解这两种方式都可以将JavaBean注入到Spring的IOC容器中。那么,使用注解将JavaBean注入到IOC容器中时,使用的bean的名称又是什么呢?我们可以在MainTest类的main方法中添加如下代码来获取Person这个类型的组件在IOC容器中的名字。

    // Person这个类型的组件在IOC容器中的名字是什么呢?
    String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
    for (String name : namesForType) {
        System.out.println(name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样,MainTest类的main方法的完整代码如下所示。

    package com.zhz;
    
    import com.zhz.bean.Person;
    import com.zhz.config.MainConfig;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author zhouhengzhe
     * @description: 测试类
     * @date 2022/11/4 10:15
     * @since v1
     */
    public class MainTest {
        public static void main(String[] args) {
    //        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
    //        Person person = (Person) applicationContext.getBean("person");
    //        System.out.println(person);
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
            Person person = applicationContext.getBean(Person.class);
            System.out.println(person);
            String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
            for (String s : beanNamesForType) {
                System.out.println(s);
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    我们可以思考一下person是什么?我们修改下MainConfig中的person()方法的名字,改成person1,如下:

    package com.zhz.config;
    
    import com.zhz.bean.Person;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author zhouhengzhe
     * @description: todo
     * @date 2022/11/4 10:27
     * @since v1
     */
    @Configuration
    public class MainConfig {
    
        @Bean
        public Person person1(){
            return new Person("zhz", 20);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    再次运行MainTest,发现名字变了,所以可以得知,其拿的是方法名做beanName(Bean的名字)
    在这里插入图片描述

    我们可以想一想@Bean里面是不是也可以命名呢,如下

    package com.zhz.config;
    
    import com.zhz.bean.Person;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author zhouhengzhe
     * @description: todo
     * @date 2022/11/4 10:27
     * @since v1
     */
    @Configuration
    public class MainConfig {
    
        /**
         * @Bean注解是给IOC容器中注册一个bean,类型自然就是返回值的类型,id默认是用方法名作为id
          */
        @Bean(name = "person")
        public Person person1(){
            return new Person("zhz", 20);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行MainTest可知:确实可以改变。
    在这里插入图片描述

    总结

    我们在使用注解方式向Spring的IOC容器中注入JavaBean时,如果没有在**@Bean注解中明确指定bean的名称**,那么就会使用当前方法的名称来作为bean的名称;如果在**@Bean注解中明确指定了bean的名称**,那么就会使用**@Bean注解中指定的名称来作为bean的名称**。

  • 相关阅读:
    不同激活函数
    基于JavaWEB+MySQL的房屋租赁网站管理系统
    Gof23设计模式之策略模式
    基于React俄罗斯方块h5小游戏源码响应式支持PC+手机
    RK3399平台开发系列讲解(内存篇)15.34、 Linux 进程内存布局
    如何为 SAST 工具设置误报基准?
    LeetCode 101Pro
    Java超详细的基础编程300题,附带答案,持续更新中~
    即时通讯开发之在WebSocket基础上实现Hybrid移动端消息推送
    2022-08-18 mysql/stonedb-aggregate场景group by分析
  • 原文地址:https://blog.csdn.net/zhouhengzhe/article/details/127896133