快速上手Spring--6. Singleton的使用与否

本文通过实例演示了Spring框架中Singleton模式的应用,并对比了原型模式的实现方式,展示了如何通过配置控制Bean的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上篇文章已经谈了 《Spring Framework 开发参考手册》的3.2.4小节——《Bean的标志符(id与name)》,现在继续3.2.5小节——《Singleton的使用与否》。
  
    文档已经把Singleton说的很清楚了,这里也不废话了。主要是了解在Spring中,默认的部署方式是Singleton,没有特别需要的话,一般使用Singleton。
 
   相关软件的配置可以参考《快速上手Spring--2.HelloWorld(1) 》。
 
    这里还是以HelloBean为例,这三个文件都放在包javamxj.spring.basic.singleton下。
 
· HelloBean 
   这里多加了属性i,用它得到随机数。
HelloBean.java
package javamxj . spring . basic . singleton ;

public class HelloBean {

    private String helloWorld;

    private int i = ( int) (100 * Math.random());

    public HelloBean( String helloWorld) {
        this.helloWorld = helloWorld;
    }

    public void sayHello() {
        System.out.println(helloWorld);
        System.out.println( "输出随机整数:  " + i);
    }
}
 
· 配置文件
    在这个Beans中,定义了两个bean,都指向HelloBean类,主要不同就是第二个bean指明了singleton="false",即不采用singleton部署方式。
bean.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="singletonBean" class="javamxj.spring.basic.singleton.HelloBean">
        <constructor-arg>
            <value>Hello! 这是singletonBean!</value>
        </constructor-arg>
    </bean>

   
<bean id="prototypeBean" class="javamxj.spring.basic.singleton.HelloBean"
        singleton="false">
        <constructor-arg>
            <value>Hello! 这是prototypeBean! </value>
        </constructor-arg>
    </bean>

</beans>
 
 
· 测试程序:
   分别取得singletonBean和prototypeBean各两个实例,然后输出随机数,最后比较同一个bean的两个实例的引用是否相同。
Main.java
package javamxj . spring . basic . singleton ;

import org . springframework . beans . factory . BeanFactory ;
import org . springframework . beans . factory . xml . XmlBeanFactory ;
import org . springframework . core . io . ClassPathResource ;
import org . springframework . core . io . Resource ;

public class Main {
    public static void main( String[] args) {

        Resource res = new ClassPathResource( "javamxj/spring/basic/singleton/bean.xml");
        BeanFactory factory = new XmlBeanFactory(res);

        HelloBean h1 = (HelloBean) factory.getBean( "singletonBean");
        h1.sayHello();       
       
        HelloBean h2 = (HelloBean) factory.getBean( "singletonBean");
        h2.sayHello();
       
        System.out.println( "h1==h2: " + (h1==h2));
        System.out.println( "");
       
       
        HelloBean h3 = (HelloBean) factory.getBean( "prototypeBean");
        h3.sayHello();
       
        HelloBean h4 = (HelloBean) factory.getBean( "prototypeBean");
        h4.sayHello();
       
        System.out.println( "h3==h4: " + (h3==h4));
    }
}
 
 
  ·运行,控制台输出:
Hello! 这是singletonBean!
输出随机整数:  7
Hello! 这是singletonBean!
输出随机整数:  7
h1==h2: true
 
Hello! 这是prototypeBean!
输出随机整数:  95
Hello! 这是prototypeBean!
输出随机整数:  60
h3==h4: false
 
 
 
·这篇文章和上篇文章的源代码下载(不包含库文件): http://free.ys168.com/?javamxj  Spring目录下面的SpringBasic.zip。

 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xmcLcdpItemController.v1': Unsatisfied dependency expressed through field 'xmcLcdpItemRepository': Error creating bean with name 'xmcLcdpItemRepositoryImpl': Injection of resource dependencies failed at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1441) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1122) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1093) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1030) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.1.jar:6.2.1] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.1.jar:6.2.1] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.4.1.jar:3.4.1] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.1.jar:3.4.1] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.1.jar:3.4.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.1.jar:3.4.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.4.1.jar:3.4.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.4.1.jar:3.4.1] at com.hand.xmc.XmcldcpApplication.main(XmcldcpApplication.java:14) ~[classes/:na] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xmcLcdpItemRepositoryImpl': Injection of resource dependencies failed at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:372) ~[spring-context-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1441) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1631) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519) ~[spring-beans-6.2.1.jar:6.2.1] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785) ~[spring-beans-6.2.1.jar:6.2.1] ... 22 common frames omitted Cau报错
最新发布
08-22
<think>嗯,用户这次遇到的错误是关于Spring Boot应用启动时的依赖注入问题,具体报错信息是“Injection of resource dependencies failed”。首先,我需要仔细分析错误日志,确定问题的根源。用户提供的日志显示,在创建xmcLcdpItemRepositoryImpl这个Bean时,资源依赖注入失败。这可能涉及到多个方面,比如依赖项未正确配置、Bean的作用域问题,或者配置错误等。 首先,我应该回顾之前的对话历史。用户之前遇到过两个问题:一个是关于Spring Boot配置属性迁移的警告,另一个是关于MyBatis中多个自增列的错误。现在的新错误与依赖注入相关,可能涉及不同的原因,但需要结合之前的上下文来判断是否有潜在关联。 用户当前的错误是UnsatisfiedDependencyException,具体在xmcLcdpItemRepositoryImpl的注入失败。根据Spring的机制,这类错误通常是因为依赖的Bean不存在,或者存在多个候选Bean导致歧义,或者Bean的作用域配置不当。另外,可能还有资源(如数据库连接)未正确配置,导致Bean无法初始化。 接下来,我需要查看错误堆栈。关键点在于“Injection of resource dependencies failed”,这通常由CommonAnnotationBeanPostProcessor处理资源注入时失败。可能的原因包括: 1. **依赖的Bean未定义或未被Spring管理**:例如,xmcLcdpItemRepositoryImpl依赖的某个服务或组件没有被正确注入,或者该Bean本身没有被Spring管理(比如缺少@Component或@Repository注解)。 2. **资源注入错误**:如果xmcLcdpItemRepositoryImpl使用了@Resource或@Autowired注解注入某些资源(如EntityManager、DataSource等),但这些资源未正确配置或注入失败。 3. **Bean作用域问题**:如果Bean的作用域配置错误(如prototype与singleton混用),可能导致注入失败。 4. **配置错误**:数据库连接池配置错误,或者MyBatis映射文件路径不正确,导致相关Bean无法初始化。 5. **类路径问题**:某些依赖库未正确包含在项目中,导致类找不到或初始化失败。 接下来,我需要考虑用户可能的项目结构。通常,Spring Boot项目中Repository接口会由Spring Data JPA或MyBatis等框架管理,而RepositoryImpl可能是自定义的实现类,可能使用了@Primary或@Component注解。如果用户使用了MyBatis,需要确认Mapper接口是否正确扫描到,或者XML映射文件是否存在错误。 另外,用户之前的错误涉及多个自增列,可能与数据库配置相关,但当前错误更偏向于依赖注入,所以需要分开考虑。不过,如果xmcLcdpItemRepositoryImpl依赖于某个数据库资源,而之前的数据库配置错误导致资源无法获取,也可能引发此问题。 可能的解决方案包括: - 检查xmcLcdpItemRepositoryImpl类是否有@Component或@Repository注解,确保其被Spring管理。 - 查看该类中是否有@Autowired或@Resource注解的字段,确认这些依赖是否正确注入。 - 确认相关的Bean是否在配置文件中正确声明,或者在配置类中通过@Bean方法定义。 - 检查Spring Boot的组件扫描路径是否包含这些类所在的包。 - 如果使用MyBatis,确认Mapper接口是否被正确扫描,或者检查数据源配置是否正确。 - 查看是否有其他嵌套的异常信息,日志中可能有更具体的错误原因,比如数据库连接失败、SQL语法错误等。 用户可能需要检查他们的依赖注入配置,确保所有需要的Bean都被正确管理,并且资源注入没有问题。此外,清理和重新构建项目,确保所有类和配置文件被正确加载,可能有助于解决此类问题。</think>### 错误分析 报错信息核心为: ``` Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xmcLcdpItemRepositoryImpl': Injection of resource dependencies failed ``` 表示 **`xmcLcdpItemRepositoryImpl` Bean 创建失败,原因是资源依赖注入异常**。 --- ### 📌 根本原因 1. **资源依赖未正确注入** - `xmcLcdpItemRepositoryImpl` 中可能使用了 `@Resource` 或 `@Autowired` 注解注入资源(如 `EntityManager`、`DataSource`、`Mapper` 等),但目标 Bean 不存在或配置错误。 2. **Bean 未被 Spring 管理** - `xmcLcdpItemRepositoryImpl` 或其依赖的组件(如 `Mapper`、`Service`)可能缺少 `@Component`、`@Repository` 或 `@Service` 注解,导致 Spring 无法管理。 3. **MyBatis 映射配置错误** - 如果使用 MyBatis,`xmcLcdpItemRepositoryImpl` 可能依赖的 `Mapper` 接口未被正确扫描,或 XML 映射文件路径错误。 4. **数据库连接异常** - 数据源配置错误(如 URL、用户名、密码错误),导致依赖的数据库资源无法初始化。 5. **类路径冲突或缺失** - 项目依赖库未正确加载(如 MyBatis、JPA、数据库驱动缺失或版本冲突)。 --- ### ✅ 解决方案 #### 1. **检查 `xmcLcdpItemRepositoryImpl` 的注解** 确保类上有 `@Component` 或 `@Repository` 注解: ```java @Repository public class XmcLcdpItemRepositoryImpl implements XmcLcdpItemRepository { // 依赖注入字段 } ``` #### 2. **验证依赖的资源是否正确注入** 检查类中 `@Autowired` 或 `@Resource` 字段: ```java @Autowired private XmcLcdpItemMapper xmcLcdpItemMapper; // 确保该 Mapper 被 Spring 管理 ``` #### 3. **确认依赖 Bean 的存在性** - **MyBatis Mapper**:确保接口有 `@Mapper` 注解或通过 XML 配置扫描: ```java @Mapper public interface XmcLcdpItemMapper { // 方法定义 } ``` - **数据源配置**:检查 `application.yml` 或 `application.properties` 中的数据库连接配置: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/your_db username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver ``` #### 4. **检查组件扫描路径** 确保 `xmcLcdpItemRepositoryImpl` 和相关组件所在的包在 Spring Boot 主类的子包内,或通过 `@ComponentScan` 显式指定: ```java @SpringBootApplication @ComponentScan("com.hand.xmc") // 确保包含目标包 public class XmcldcpApplication { public static void main(String[] args) { SpringApplication.run(XmcldcpApplication.class, args); } } ``` #### 5. **查看嵌套异常日志** 在日志中查找更具体的错误(如数据库连接失败、SQL 语法错误等): ``` Caused by: java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=localhost)(port=3306) ``` #### 6. **清理并重新构建项目** 执行以下命令确保依赖正确加载: ```bash mvn clean install # Maven gradle clean build # Gradle ``` --- ### 🧪 验证修复 1. **启动应用**:检查是否仍有 `BeanCreationException`。 2. **调用接口**:验证 `xmcLcdpItemRepositoryImpl` 的功能是否正常。 3. **日志检查**:确认数据库连接、Mapper 加载等关键步骤无异常。 --- ### 📌 注意事项 1. **MyBatis 多模块项目** - 如果使用 MyBatis XML 映射文件,确保路径在 `resources` 目录下且与 Mapper 接口路径匹配。 2. **依赖版本兼容性** - 确保 Spring Boot、MyBatis、数据库驱动版本兼容(如 Spring Boot 3.x 需使用 Jakarta EE 9+)。 3. **日志详细级别** - 启用 SQL 日志输出以排查 MyBatis 问题: ```yaml logging: level: com.hand.xmc.infra.mapper: debug # 显示 MyBatis SQL 日志 ``` --- ### 📚 参考资料 - [Spring Boot 官方文档 - 依赖注入](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#io.choerodon.mybatis.domain.AuditDomain) - [MyBatis Spring 集成指南](https://mybatis.org/spring/zh/index.html) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值