【IoCDI】_方法注解@Bean

embedded/2025/2/6 0:01:47/

目录

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类,在启动类中进行测试:

java">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类:

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

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

java">package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;public class BeanConfig {@Beanpublic UserInfo userInfo(){UserInfo userInfo1=new UserInfo();userInfo1.setId(1);userInfo1.setName("zhangsan");userInfo1.setAge(20);return userInfo1;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo2=new UserInfo();userInfo2.setId(2);userInfo2.setName("lisi");userInfo2.setAge(21);return userInfo2;}
}

在运行类中尝试获取UserInfo:

java">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注解:

java">package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){UserInfo userInfo1=new UserInfo();userInfo1.setId(1);userInfo1.setName("zhangsan");userInfo1.setAge(20);return userInfo1;}@Beanpublic 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的名称,修改启动类程序如下:

java">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的名称+类型,修改启动类程序如下:

java">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.ppmy.cn/embedded/159881.html

相关文章

SQL入门到精通 理论+实战 -- 在 MySQL 中学习SQL语言

目录 一、环境准备 1、MySQL 8.0 和 Navicat 下载安装 2、准备好的表和数据文件: 二、SQL语言简述 1、数据库基础概念 2、什么是SQL 3、SQL的分类 4、SQL通用语法 三、DDL(Data Definition Language):数据定义语言 1、操…

64位的谷歌浏览器Chrome/Google Chrome

64位的谷歌浏览器Chrome/Google Chrome 在百度搜索关键字:chrome,即可下载官方的“谷歌浏览器Chrome/Google Chrome”,但它可能是32位的(切记注意网址:https://www.google.cn/...., 即:google.cn&#xff…

HAO的Graham学习笔记

前置知识:凸包 摘录oiwiki 在平面上能包含所有给定点的最小凸多边形叫做凸包。 其定义为:对于给定集合 X,所有包含 X 的凸集的交集 S 被称为 X 的 凸包。 说人话就是用一个橡皮筋包含住所有给定点的形态 如图: 正题&#xff1a…

赛博算卦之周易六十四卦JAVA实现:六幺算尽天下事,梅花化解天下苦。

佬们过年好呀~新年第一篇博客让我们来场赛博算命吧! 更多文章:个人主页 系列文章:JAVA专栏 欢迎各位大佬来访哦~互三必回!!! 文章目录 #一、文化背景概述1.文化起源2.起卦步骤 #二、卦象解读#三、just do i…

解密 Argon2:Java 密码加密的高安全实践与趣味探索

前言 欢迎来到 Argon2 加密的奇妙世界!也许你已经对那些老掉牙的加密算法(比如 MD5、SHA 和 BCrypt)耳熟能详,而今天,我们要为你介绍一位全新的安全“超级英雄”——Argon2。为什么选择 Argon2?因为它不仅能为你的密码提供前所未有的安全防护,还能让那些试图破解它的黑…

《苍穹外卖》项目学习记录-Day11订单统计

根据起始时间和结束时间,先把begin放入集合中用while循环当begin不等于end的时候,让begin加一天,这样就把这个区间内的时间放到List集合。 查询每天的订单总数也就是查询的时间段是大于当天的开始时间(0点0分0秒)小于…

深入探索SQL中修改表字段属性的技巧与策略

摘要 在SQL中,修改表字段属性是一项常见的数据库管理任务。用户可以调整字段的数据类型、长度、默认值或注释,而无需更改字段名称。例如,varchar类型可转换为mediumtext或text,NVARCHAR2类型可转换为NCLOB。若需同时变更字段名称及…

Spring Boot 日志:项目的“行车记录仪”

一、什么是Spring Boot日志 (一)日志引入 在正式介绍日志之前,我们先来看看上篇文章中(Spring Boot 配置文件)中的验证码功能的一个代码片段: 这是一段校验用户输入的验证码是否正确的后端代码&#xff0c…