当前位置: 首页 > article >正文

【IoCDI】_方法注解@Bean

目录

1. 类注解的使用局限

2. 仅使用@Bean注解

3. 五大注解配合使用@Bean

3.1 使用方式1:getBean传参Bean类型

3.2 使用方式2:getBean传参Bean名称

3.3 使用方式3:getBean传参Bean名称+类型


在上文中,已经介绍了五大类注解及getBean方法的使用,详见下文:

【Ioc&DI】_存储Bean的五大类注解及getBean的使用-CSDN博客文章浏览阅读607次,点赞6次,收藏18次。(1) 类注解:@Controller、@Service、@Repository、@Component、@Configuration;在系统中,对于非Controller层、非Service层和非Dao层的其他bean,使用@Component注解实现存储;在上文实现IoC基本存取功能的两个注解中,要把某个对象交给IOC容器管理,需要在类上添加⼀个@Component注解。(@Controller、@Service、@Repository与三层架构分别对应)https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118https://blog.csdn.net/m0_63299495/article/details/145421932?sharetype=blogdetail&sharerId=145421932&sharerefer=PC&sharesource=m0_63299495&spm=1011.2480.3001.8118已经了解到:

Spring提供的注解可分为两大类:

1、类注解:@Controller、@Service、@Repository、@Component、@Configuration;

2、方法注解:@Bean;

基于已经了解的五大类注解的相关知识,现介绍方法注解@Bean。

1. 类注解的使用局限

在上文(见链接)中,已经提到,五大注解只能加在类上。

除此之外,类注解还有2个局限性:

1、五大注解只能加在类上,并且只能加在自己的代码上

如果引入了一个第三方的Jar包也希望交给Spring管理,则无法加五大注解。

2、通过类注解修饰的bean在Spring容器中仅存储一份

对于一个类,定义多个对象(如数据库操作定义多个数据源)时,类注解也是无法发挥作用的。

注:对于第2条,可以进行测试:

在Config包下创建一个UserConfig类,在启动类中进行测试:

package com.example.iocdemo1;

import com.example.iocdemo1.Config.UserConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class IoCDemo1Application {
    public static void main(String[] args) {
        ApplicationContext context=
                SpringApplication.run(IoCDemo1Application.class, args);

        UserConfig config1 = context.getBean(UserConfig.class);
        System.out.println("config1: "+config1);

        UserConfig config2=context.getBean(UserConfig.class);
        System.out.println("config2: "+config2);
        System.out.println("config1 == config2? "+(config1 == config2));
    }
}

启动项目查看日志:

可见config1与config2地址相同,本质上是一个对象。可见使用类注解修饰的类,在容器当中仅存储了一份,无论使用getBean取出多少次,取出的都是同一个bean;

2. 仅使用@Bean注解

在Config包下创建一个UserInfo类:

package com.example.iocdemo1.Config;
import lombok.Data;
@Data
public class UserInfo {
    private int id;
    private String name;
    private int age;
}

在同个包下再创建一个BeanConfig类:

package com.example.iocdemo1.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class BeanConfig {
    @Bean
    public UserInfo userInfo(){
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(1);
        userInfo1.setName("zhangsan");
        userInfo1.setAge(20);
        return userInfo1;
    }
    @Bean
    public UserInfo userInfo2(){
        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(2);
        userInfo2.setName("lisi");
        userInfo2.setAge(21);
        return userInfo2;
    }
}

在运行类中尝试获取UserInfo:

package com.example.iocdemo1;

import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class IoCDemo1Application {
    public static void main(String[] args) {
        ApplicationContext context=
                SpringApplication.run(IoCDemo1Application.class, args);

        UserInfo userInfo = context.getBean(UserInfo.class);
        System.out.println(userInfo);
    }
}

运行程序,报错如下:

表示未找到类型为UserInfo.class的bean。

3. 五大注解配合使用@Bean

3.1 使用方式1:getBean传参Bean类型

在2.1部分,已完成了在BeanConfig类的方法前使用@Bean注解。

启动程序发现,程序抛异常:NoSuchBeanDefinitionException,这与Spring的扫描机制有关。

Spring通过扫描注解来明确需要管理的bean,但扫描并不全盘扫描方法注解。

对于方法注解@Bean,需要配合使用五大注解才能将对象正确存储到容器中

在BeanConfig类前增加@Configuration注解:

package com.example.iocdemo1.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfig {
    @Bean
    public UserInfo userInfo(){
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(1);
        userInfo1.setName("zhangsan");
        userInfo1.setAge(20);
        return userInfo1;
    }
    @Bean
    public UserInfo userInfo2(){
        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(2);
        userInfo2.setName("lisi");
        userInfo2.setAge(21);
        return userInfo2;
    }
}

保持其他类程序不变,重新启动程序:

启动程序发现,程序抛异常:NoUniqueBeanDefinitionException,表示当前扫描到两个bean,一个bean名为userInfo,一个bean名为userInfo2;

再次对应启动类相关代码,当前使用方式中,Spring无法识别bean的原因在于:

以传参为Bean类型调用getBean时,若一个类型存在多个Bean时,就会使得Spring无法确定到底要使用哪个类

注:关于不同注解方式下的bean的名称:

使用@Bean注解时,bean的名称是方法名

使用五大注解时,bean的名称是类名的小驼峰表示法,且当类名前两个字母均为大写时,bean名即类名

3.2 使用方式2:getBean传参Bean名称

针对某类型存在多个Bean时,使用方式1存在的问题,可采用第2种使用方式。

给getBean方法传参Bean的名称,修改启动类程序如下:

package com.example.iocdemo1;

import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class IoCDemo1Application {
    public static void main(String[] args) {
        ApplicationContext context=
                SpringApplication.run(IoCDemo1Application.class, args);

        UserInfo userInfo1 = (UserInfo) context.getBean("userInfo");
        System.out.println(userInfo1);
        UserInfo userInfo2 = (UserInfo) context.getBean("userInfo2");
        System.out.println(userInfo2);
    }
}

重新启动程序:

注:对于给getBean方法传参Bean的名称(方式2)需要强制类型转换

3.3 使用方式3:getBean传参Bean名称+类型

对某类型存在多个Bean,使用方式1存在的问题,除第2种使用方式外,可采用第3种使用方式。

给getBean方法传参Bean的名称+类型,修改启动类程序如下:

package com.example.iocdemo1;

import com.example.iocdemo1.Config.UserInfo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class IoCDemo1Application {
    public static void main(String[] args) {
        ApplicationContext context=
                SpringApplication.run(IoCDemo1Application.class, args);
        UserInfo userInfo1=context.getBean("userInfo",UserInfo.class);
        System.out.println(userInfo1);
        UserInfo userInfo2=context.getBean("userInfo2", UserInfo.class);
        System.out.println(userInfo2);
    }
}

重新启动程序:

注:相较于给getBean方法传参Bean的名称(方式2),getBean方法传参Bean的名称+类型(方式3)无需强制类型转换


http://www.kler.cn/a/532469.html

相关文章:

  • [创业之路-273]:《发现利润区》的主要内容与核心思想
  • HTMLCSS :下雪了
  • Redis常见命令
  • Debezium Oracle Connector SCN处理优化指南
  • 【集成Element Plus】
  • 新月军事战略分析系统使用手册
  • 数字化转型:概念性名词浅谈
  • 【后端面试总结】ES的_template与_index_template技术详解
  • 【Linux系统】CPU指令集 和 Linux系统权限 ring 0 / ring 3
  • Day35-【13003】短文,什么是顺序队列,链式队列,链式队列如何结合空闲单元链表使用?
  • React+AI 技术栈(2025 版)
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.27 NumPy+Pandas:高性能数据处理的黄金组合
  • 7-9 乘法口诀数列
  • 《chatwise:DeepSeek的界面部署》
  • AMD架构简单读书笔记3——内存模型1
  • 【Unity2D 2022:C#Script】DoTween插件的使用
  • VLAN 基础 | 不同 VLAN 间通信实验
  • Java-数据结构-优先级队列(堆)
  • 正态分布和标准正态分布区别与联系(复习)
  • Modbus Slave RTU 在 AVP28335(兼容德州仪器TMS 320 28335) 上实现含源码及注释。
  • deepseek本地部署及可视化输入
  • 中国城商行信贷业务数仓建设白皮书(第二期:信贷主题域建模)
  • 图论常见算法
  • 青少年编程与数学 02-008 Pyhon语言编程基础 12课题、条件与循环语句
  • Python零基础快速入门课程,自带在线运行环境
  • 网络原理一> ip协议相关特性