【问题标题】:Spring Boot: How to inject a RepositorySpring Boot:如何注入存储库
【发布时间】:2020-12-22 21:19:04
【问题描述】:

我有一个使用 Spring Data 和 JPA 的 Spring Boot 应用程序。因此,我为数据实体编写了存储库类(实际上是接口),并且我有@Services 来提供一种处理数据的方法。

我遇到了一个问题,我不知道如何将存储库注入到服务类中。在其他情况下,我会编写一个带有@Bean 定义的@Configuration 类来提供需要注入的项目。

这在这里行不通,因为我没有注入类实例化,而是需要Repository 接口的某种实现。

我在 Vaadin Spring Boot 应用程序中使用了这种技术,该应用程序具有识别、创建/生成和注入所需内容的内置支持。对于基本操作,不需要创建any实现类。

效果很好,但我这里没有。我不想让应用程序成为 Vaadin 应用程序只是为了获得存储库注入的好处。我该怎么做?

更新

我已经尝试了建议的方法,但仍然没有骰子。我一定缺少一些基本的东西。

这里有一些sn-ps:

AppConfig.java:

@Configuration
public class AppConfig {
  @Bean
  public TaskMasterService tmService(final TaskMasterRepository repo) {
    return new TaskMasterService(repo);
  }
  // Other @Bean definitions    
}

DataIngester.java:(“主要”)

@SpringBootApplication
public class DataIngester {
  public static void main(String[] args) {
    SpringApplication.run(DataIngester.class, args);
  }
}

IngesterRunner.java:

@Component
public class IngesterRunner implements CommandLineRunner {
  private TaskMasterService       tmService;
  private TaskRelationshipService trService;
  private VariantDetailService    vdService;

  @Autowired
  public IngesterRunner(TaskMasterService tmService, TaskRelationshipService trService,
      VariantDetailService vdService) {
    this.tmService = tmService;
    this.trService = trService;
    this.vdService = vdService;
  }

  @Override
  public void run(String... args) throws Exception {
    ...
  }

}

TaskMasterService.java:

@Service
@Transactional
public class TaskMasterService {
  private final TaskMasterRepository repo;

  @Autowired
  public TaskMasterService(TaskMasterRepository repo) {
    this.repo = repo;
  }
  ...
}

TaskMasterRepository.java:

@Repository
public interface TaskMasterRepository extends JpaRepository<TaskMaster, Long> {
}

控制台输出:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

2020-12-23 07:31:12.972  INFO workstation --- [  restartedMain] c.f.e.i.DataIngester                     : Starting DataIngester on workstation with PID 23800 (C:\Users\jgagnon\workspace\java\e1-task-info2\target\classes started by jgagnon in C:\Users\jgagnon\workspace\java\e1-task-info2)
2020-12-23 07:31:12.975  INFO workstation --- [  restartedMain] c.f.e.i.DataIngester                     : No active profile set, falling back to default profiles: default
2020-12-23 07:31:13.007  INFO workstation --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-12-23 07:31:13.364  INFO workstation --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.
2020-12-23 07:31:13.382  INFO workstation --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11ms. Found 0 JPA repository interfaces.
2020-12-23 07:31:13.636  INFO workstation --- [  restartedMain] o.s.s.c.ThreadPoolTaskExecutor           : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-23 07:31:13.661  WARN workstation --- [  restartedMain] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ingesterRunner' defined in file [C:\Users\jgagnon\workspace\java\e1-task-info2\target\classes\com\mycompany\app\ingest\IngesterRunner.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.mycompany.app.backend.service.TaskMasterService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2020-12-23 07:31:13.661  INFO workstation --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-12-23 07:31:13.668  INFO workstation --- [         task-1] o.h.j.i.u.LogHelper                      : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-12-23 07:31:13.713  INFO workstation --- [         task-1] o.h.Version                              : HHH000412: Hibernate ORM core version 5.4.20.Final
2020-12-23 07:31:13.838  INFO workstation --- [         task-1] o.h.a.c.Version                          : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-12-23 07:31:13.937  INFO workstation --- [         task-1] c.z.h.HikariDataSource                   : HikariPool-1 - Starting...
2020-12-23 07:31:14.112  INFO workstation --- [         task-1] c.z.h.HikariDataSource                   : HikariPool-1 - Start completed.
2020-12-23 07:31:14.128  INFO workstation --- [         task-1] o.h.d.Dialect                            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2020-12-23 07:31:14.342  INFO workstation --- [         task-1] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-12-23 07:31:14.348  INFO workstation --- [         task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
Exception in thread "task-2" 2020-12-23 07:31:14.352  INFO workstation --- [  restartedMain] o.s.s.c.ThreadPoolTaskExecutor           : Shutting down ExecutorService 'applicationTaskExecutor'
2020-12-23 07:31:14.353  INFO workstation --- [  restartedMain] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown initiated...
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'springApplicationAdminRegistrar': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:212)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
    at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:245)
    at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:197)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:134)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:99)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.access$100(DataSourceInitializedPublisher.java:50)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher.lambda$postProcessEntityManagerFactory$0(DataSourceInitializedPublisher.java:200)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
2020-12-23 07:31:14.379  INFO workstation --- [  restartedMain] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown completed.
2020-12-23 07:31:14.384  INFO workstation --- [  restartedMain] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-23 07:31:14.503 ERROR workstation --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.mycompany.app.ingest.IngesterRunner required a bean of type 'com.mycompany.app.backend.service.TaskMasterService' that could not be found.


Action:

Consider defining a bean of type 'com.mycompany.app.backend.service.TaskMasterService' in your configuration.

【问题讨论】:

  • @Repository注解存储库类,并在@Service注解类中注入@Autowire

标签: java spring-boot spring-data repository


【解决方案1】:

像其他依赖项(又名 spring bean)一样自动装配您的存储库:

@Repository
public interface YourRepository extends CrudRepository<YourEntity, String> {
  // …
}

@Service
public class YourService {
  private final YourRepository repo;

  @Autowired
  public YourService(final YourRepository repo) {
    this.repo = repo;
  }

  public Object method() {
    // use your dependency:
    this.repo.findById(…);
  }
}

【讨论】:

    【解决方案2】:

    它应该开箱即用。

    @Component
    public class MyService {
        private final MyRepository myRepository;
    
        public MyService(MyRepository myRepository) {
            this.myRepository = myRepository;
        }
    }
    

    或带有附加配置类的版本:

    public class MyService {
        private final MyRepository myRepository;
    
        public MyService(MyRepository myRepository) {
            this.myRepository = myRepository;
        }
    }
    
    @Configuration
    public class MyConfiguration {
        @Bean MyService myService(MyRepository myRepository) {
            return new MyService(myRepository);
        }
    }
    

    【讨论】:

      【解决方案3】:

      简单的解决方案:将“main”类向上移动到源路径“root”。我把它放在一个包裹里。 [捂脸]

      【讨论】:

      • 当然,您的所有服务和存储库都必须通过组件扫描或配置来获取;)
      猜你喜欢
      • 2020-09-19
      • 2018-05-07
      • 2021-11-07
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-06
      相关资源
      最近更新 更多