php网站开发过程考试,wifi扩展器做网站,英文网站的建设,cms网站建设的方法【Spring Boot 3】获取已注入的Bean 背景介绍开发环境开发步骤及源码工程目录结构总结 背景
软件开发是一门实践性科学#xff0c;对大多数人来说#xff0c;学习一种新技术不是一开始就去深究其原理#xff0c;而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历… 【Spring Boot 3】获取已注入的Bean 背景介绍开发环境开发步骤及源码工程目录结构总结 背景
软件开发是一门实践性科学对大多数人来说学习一种新技术不是一开始就去深究其原理而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中每次学习新技术总是要花费或多或少的时间、检索不止一篇资料才能得出一个可工作的DEMO这占用了我大量的时间精力。因此本文旨在通过一篇文章即能还原出可工作的、甚至可用于生产的DEMO期望初学者能尽快地迈过0到1的这一步骤并在此基础上不断深化对相关知识的理解。 为达以上目的本文会将开发环境、工程目录结构、开发步骤及源码尽量全面地展现出来文字描述能简则简能用代码注释的绝不在正文中再啰嗦一遍正文仅对必要且关键的信息做重点描述。
介绍
本文介绍开发Spring Boot应用如何获取已注入的Bean实例。
开发环境
分类名称版本操作系统WindowsWindows 11JDKOracle JDK21.0.1IDEIntelliJ IDEA2023.3.4构建工具Apache Maven3.9.6
开发步骤及源码
1 创建Maven工程添加依赖。
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.jiyongliang/groupIdartifactIdspringboot3-bean/artifactIdversion0.0.1/version/parentartifactIdspringboot3-bean-obtain/artifactIdpropertiesjava.version21/java.versionmaven.compiler.source21/maven.compiler.sourcemaven.compiler.target21/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncodingspring-boot.version3.2.2/spring-boot.versionlombok.version1.18.30/lombok.version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/version/dependency/dependenciesbuildpluginManagementpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversion${spring-boot.version}/version/plugin/plugins/pluginManagementpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build
/project2 定义SpringBoot应用启动类。
package org.example.springboot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication
public class SpringBoot3BeanObtainApplication {public static void main(String[] args) {SpringApplication.run(SpringBoot3BeanObtainApplication.class, args);}
}3 定义获取已注入Bean的核心类。
package org.example.springboot.manager;import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;Component
Getter
Slf4j
public class BeanManager {private final ApplicationContext applicationContext;public BeanManager(ApplicationContext applicationContext) {this.applicationContext applicationContext;}/*** 通过Bean名称获取*/public Object getBean(String name) {try {return this.applicationContext.getBean(name);} catch (NoSuchBeanDefinitionException e) {log.error(e.getMessage());return null;}}/*** 通过Bean类型获取* 如果存在同一类型的多个Bean实例则会抛出NoSuchBeanDefinitionException异常信息expected single matching bean but found 2*/public T T getBean(ClassT clazz) {try {return this.applicationContext.getBean(clazz);} catch (NoSuchBeanDefinitionException e) {log.error(e.getMessage());return null;}}/*** 通过Bean名称和类型获取*/public T T getBean(String name, ClassT clazz) {try {return this.applicationContext.getBean(name, clazz);} catch (NoSuchBeanDefinitionException e) {log.error(e.getMessage());return null;}}
}4 定义测试Bean。
package org.example.springboot.bean;import lombok.AllArgsConstructor;
import lombok.Data;AllArgsConstructor
Data
public class CustomBean {private Integer id;private String name;
}5 配置注入Bean。
package org.example.springboot.config;import org.example.springboot.bean.CustomBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class CustomBeanConfig {Bean(beanX)public CustomBean beanX() {return new CustomBean(1, Bean-X);}Bean(beanY)public CustomBean beanY() {return new CustomBean(2, Bean-X);}
}6 创建单元测试。
package org.example.springboot.manager;import jakarta.annotation.Resource;
import org.assertj.core.api.Assertions;
import org.example.springboot.bean.CustomBean;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;SpringBootTest
class BeanManagerTests {AutowiredBeanManager beanManager;Resource(name beanX)CustomBean beanX;Resource(name beanY)CustomBean beanY;Testvoid test() {System.out.println(Test get bean by name);Assertions.assertThat(beanManager.getBean(beanX)).isSameAs(beanX);Assertions.assertThat(beanManager.getBean(beanY)).isSameAs(beanY);System.out.println(Test get bean by type);Assertions.assertThat(beanManager.getBean(CustomBean.class)).isNull();System.out.println(Test get bean by name and type);Assertions.assertThat(beanManager.getBean(beanX, CustomBean.class)).isSameAs(beanX);Assertions.assertThat(beanManager.getBean(beanY, CustomBean.class)).isSameAs(beanY);}
}7 单元测试结果。
单元测试日志
Test get bean by name
Test get bean by type
2024-03-08T20:31:34.84508:00 ERROR 18872 --- [ main] o.e.springboot.manager.BeanManager : No qualifying bean of type org.example.springboot.bean.CustomBean available: expected single matching bean but found 2: beanX,beanY
Test get bean by name and type从日志中可以看出测试根据类型获取注入的Bean时抛出了异常因为找到2个同样类型的Bean无法判断应该返回哪个Bean因此通过类型获取Bean时有且仅有一个类型匹配的Bean才会正常返回。
工程目录结构 总结
测试用的Bean和配置注入放在 src/test 目录下是为了辅助测试。