使用调度程序 - BeanCreationNotAllowed的 Spring 引导异常:创建名为"entityManagerFactory"的 Bean 时出错:不允许创建单例 Bean



我们有一个带有调度器的spring-boot项目,它以固定的间隔从数据库中读取数据。

当使用maven从STS构建项目时,我们在控制台中收到以下错误,同时运行测试用例,即使最终构建状态为成功。

org.springframework.beans.factory.BeanCreationNotAllowedException:创建名为"entityManagerFactory"的bean时出错:Singleton bean此工厂的单身人员在时不允许创建destroy(不要在destroy中向BeanFactory请求bean方法实现!)在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory:java:299)在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)在org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523)在org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludengAncestors(BeanFactoryUtils.java:276)在org.springframework.do.support.PersistenceExceptionTranslationInterceptor.dedetectPersistenceExceptiontranslators(PersistenceExceptionTranslationInterceptor.java:162)在org.springframework.do.support.PersistenceExceptionTranslationInterceptor.ioke(PersistenceExceptionTranslationInterceptor.java:145)在org.springframework.aop.framework.ReflectiveMethodInvocation.prough(ReflectiveMethodInvocation.java:179)在org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodmetadataPopulatingMethodInterceptor。invoke(CrudMethodMetadataPostProcessor.java:122)在org.springframework.aop.framework.ReflectiveMethodInvocation.prough(ReflectiveMethodInvocation.java:179)在org.springframework.aop.enterceptor.ExposeInvocationInterceptor.ioke(ExposeInvocationInterceptor.java:92)在org.springframework.aop.framework.ReflectiveMethodInvocation.prough(ReflectiveMethodInvocation.java:179)在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynaticalAopProxy:java:207)在com.sun.proxy.$Proxy70.findByTraIdAndTransactionNameAndExecutionTime(未知来源)

应用程序文件

@SpringBootApplication
@PropertySource("classpath:application.properties")
@EnableScheduling
public class ProvisioningApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProvisioningApplication.class, args);
    }
}

调度程序文件

BusinessService具有读取数据库的逻辑

@Component
public class SchedulerJob {
    @Autowired
    BusinessService service;
    @Scheduled(fixedRate=300000) //5mnts
    public void schdeule() {
        service.startService();
    }
}

测试文件

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProvisioningApplication.class)
public class ProvisioningApplicationTests {
    @Test
    public void contextLoads() {
    }
}

这里的问题是,为什么spring-boot在构建项目时运行调度器任务,以及为什么它会抛出上述异常

Spring Boot中,当您进行maven构建时,默认情况下会运行测试用例。在这种情况下,运行集成测试脚本,这些脚本将尝试连接到您的数据库。因为在您的项目中,作为集成测试的一部分,您没有任何需要改进的地方。一种可能的解决方案是将类ProvisioningApplicationTests声明为抽象。这将限制ProvisioningApplicationTests类的实例创建。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProvisioningApplication.class)
public abstract class ProvisioningApplicationTests {
    @Test
    public void contextLoads() {
    }
  }

解决这个问题的另一种方法是在pom.xml 中包含以下代码

<plugins>
   <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
     <skipTests>false</skipTests>
     <excludes>
      <exclude>**/*IT.java</exclude>
     </excludes>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <executions>
     <execution>
      <id>integration-test</id>
      <goals>
       <goal>integration-test</goal>
      </goals>
      <configuration>
       <skipTests>true</skipTests>
       <includes>
        <include>**/*IT.class</include>
       </includes>
      </configuration>
     </execution>
    </executions>
   </plugin>
  </plugins>

这将排除在构建项目时要执行的集成测试类maven-surefire插件用于运行单元测试maven故障保护插件用于运行集成测试。使用这种方法时,请确保所有集成类文件名都以'IT'结尾。例如UserTestIT.java

最新更新