Spring Boot和多模块Maven项目 [英] Spring Boot And Multi-Module Maven Projects

查看:106
本文介绍了Spring Boot和多模块Maven项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力获取正确的多模块Spring Boot Maven项目设置.有没有我可以参考的示例项目?目前,我的项目结构是这样的.

I am struggling to get a multi-module Spring Boot Maven project setup correctly. Are there any example projects that I can reference? Currently I have my project structured like this.

数据模块: 基本上是我的数据层.是包含我的POJO和我的数据库存储库接口(PagingAndSortingRepository).该模块将是项目中其他模块的依赖项.目前,我已将Config类放置在类似于

Data Module: Basically my data layer. Is contains my POJOs and my database repo interfaces (PagingAndSortingRepository). This module will be a dependency of the other modules in the project. Currently I have placed a Config class in the module that looks like this

public class Config {

  @Configuration
  @Profile("cloud")
  static class CloudConfiguration extends AbstractCloudConfig {
    @Bean
    public DataSource dataSource() {
      return connectionFactory().dataSource("session-questions-sql", new DataSourceConfig(new PoolConfig(4, 4), new ConnectionConfig("")));
    }

  }


  @Configuration
  @Profile("default")
  static class LocalConfiguration {
  }
}

我认为此配置在其他两个模块之间是通用的,因此它属于数据模块.

I figured this configuration would be common between the other two modules so it belonged in the data module.

文本模块: 这是一个非常简单的模块,它包含一个REST API控制器,当文本消息发送到某个电话号码时将被调用.它将文本消息存储在DB中,并使用cdata模块中的存储库接口之一来执行此操作.该模块被构建为可执行的jar文件,并且包含一个实现EmbeddedServletContainerCustomizer的类.

Text Module: The is a very simple module, it contains a single REST API controller that will be called when a text message is sent to a certain phone number. It stores the text message in the DB and uses one of the repo interfaces from the cdata module to do so. This module is being built as an executable jar file and contains a class which implements EmbeddedServletContainerCustomizer.

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableJpaRepositories
public class App implements EmbeddedServletContainerCustomizer {

  public static void main(String[] args) throws Exception {
      SpringApplication.run(App.class, args);
  }

  @Override
  public void customize(ConfigurableEmbeddedServletContainer container) {
    //Enabled UTF-8 as the default character encoding for static HTML resources.
    //If you would like to disable this comment out the 3 lines below or change
    //the encoding to whatever you would like.
    MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
    mappings.add("html", "text/html;charset=utf-8");
    container.setMimeMappings(mappings );
  }
}

运行jar时,出现错误,提示rest控制器类无法从数据模块自动装配bean.我看到一些帖子说您应该将包名称添加到@ComponentScan批注中.例如

When I run the jar I get errors saying that rest controller class cannot autowire beans from my data module. I saw some posts saying that you should add the package name to the @ComponentScan annotation. For example

@ComponentScan("com.example.data")

@ComponentScan("com.example.data")

执行此操作将使嵌入式tomcat服务器启动,但是我认为仅添加该程序包会使Spring在文本模块中找不到我的REST控制器,因为在访问API时会收到404.所以我也添加了文字包

Doing this will let the embedded tomcat server start, but I think adding that package alone causes Spring to not find my REST controller in my text module because I am getting 404s when hitting the API. So I added my text package as well

@ComponentScan({"com.example.data","com.example.text"})

@ComponentScan({"com.example.data","com.example.text"})

但是,这又使我回到了相同的错误,Spring无法从数据模块中找到要自动连接到我的REST控制器的bean.

However this brings me back to the same error, Spring cannot find my beans from the data module to autowire to my REST controller.

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'twilioController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.data.controllers.QuestionRepo com.example.questions.text.controller.TwilioController.questionRepo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.data.controllers.QuestionRepo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
    at com.example.text.App.main(App.java:34)
    ... 6 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.data.controllers.QuestionRepo com.example.text.controller.TwilioController.questionRepo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.data.controllers.QuestionRepo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 22 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.data.controllers.QuestionRepo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 24 more

有人对如何正确执行操作有任何指示吗?

Does anyone have any pointers on how to do this properly?

推荐答案

系统会自动从应用程序类的程序包(用@EnableAutoConfiguration注释的程序包)中扫描存储库.如果该默认值不适合您,则可以使用相关的软件包轻松回退到@EnableJpaRepositories.

The repositories are scanned automatically from the package of your application class (the one annotated with @EnableAutoConfiguration). If that default does not suit you, you can easily fallback on @EnableJpaRepositories with the relevant packages.

我可以看到com.example.datacom.example.text.我想您可能有一个特定于项目的软件包,因为com.example可能范围太广.因此,解决此问题的一种方法是将您的应用程序放入com.example(或应用程序的根软件包).

I can see com.example.data and com.example.text. I guess you might have a project specific package as com.example is probably too broad. So one way to fix that would be to put your application in com.example (or whatever the root package of your app is).

还要该doc

这篇关于Spring Boot和多模块Maven项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆