java Spring Boot 多模块 Maven 项目@Autowired 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32384029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:07:35  来源:igfitidea点击:

Spring Boot multi module Maven project @Autowired does not work

javaspringmavenspring-bootautowired

提问by ACV

This is really strange. I started my Spring Boot project as a single maven project and all worked perfectly. Basically it is a Spring MVC app with security and mail.

这真的很奇怪。我将 Spring Boot 项目作为一个单独的 Maven 项目开始,并且一切正常。基本上它是一个具有安全性和邮件功能的 Spring MVC 应用程序。

Then when I saw that some components like service, repository, model will be reused by a standalone application, I decided to split the maven project into sub-modules.

然后当我看到一些组件如服务、存储库、模型将被一个独立的应用程序重用时,我决定将 maven 项目拆分为子模块。

Suddenly no autowiring started to work. After some investigation I found out that I need to explicitly put the packages in my Application of the standalone app:

突然间没有自动装配开始工作。经过一番调查,我发现我需要明确地将包放在我的独立应用程序的应用程序中:

@ComponentScan (basePackages={"service"})
@EnableJpaRepositories(basePackages={"repository"})
@EnableAutoConfiguration
@EntityScan(basePackages={"model"})

OK, after that my custom classes started getting autowired. But another problem appeared:

好的,在那之后我的自定义类开始自动装配。但是出现了另一个问题:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.mail.javamail.JavaMailSender service.impl.UserServiceImpl.mailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] 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:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.me.newsaggregator.rsscollector.RsscollectorApplication.main(RsscollectorApplication.java:18)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.mail.javamail.JavaMailSender service.impl.UserServiceImpl.mailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] 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:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] 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:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)

So it looks like standard packages are not getting autowired anymore. pom.xml of this standalone app:

所以看起来标准包不再自动装配了。这个独立应用程序的 pom.xml:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.5.4</version>
    </dependency>

Please help.

请帮忙。

回答by ACV

Finally I got it working. Besides adding the above mentioned annotations I had to:

最后我让它工作了。除了添加上述注释外,我还必须:

  1. Add the class MailConfigurationinto the package where the standalone application resided (com.my.newsaggregator.rsscollector)
  2. Add the standalone application base package (com.my.newsaggregator.rsscollector) to @ComponentScan
  1. 将该类添加MailConfiguration到独立应用程序所在的包中 ( com.my.newsaggregator.rsscollector)
  2. 将独立应用程序基础包 ( com.my.newsaggregator.rsscollector) 添加到@ComponentScan

Here is what I mean:

这就是我的意思:

package com.my.newsaggregator.rsscollector;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@ComponentScan (basePackages={"service","com.my.newsaggregator.rsscollector"})
@EnableJpaRepositories(basePackages={"repository"})
@EnableAutoConfiguration
@EntityScan(basePackages={"model"})

public class RsscollectorApplication {

    public static void main(String[] args) {
        SpringApplication.run(RsscollectorApplication.class, "--debug").close();
        System.out.println("done");

    }
}

By the way, the same will happen to your JUnit tests. In my case I got an error about Spring Security not being autowired.

顺便说一下,您的 JUnit 测试也会发生同样的情况。就我而言,我收到有关 Spring Security 未自动装配的错误。

回答by Bruce

A very easy way to fix this: Set the

一个非常简单的方法来解决这个问题:设置

scanBasePackages

扫描基础包

to your root package, to me is :org.umasuo, so that the spring can scan all the class you need to scan.

到你的根包,对我来说是 : org.umasuo,这样 spring 就可以扫描你需要扫描的所有类。

@SpringBootApplication(scanBasePackages = "you.root.package")
public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

Actually, we can have a look at how the spring do the package scan, so that we can know it well.

其实我们可以看看spring是怎么做包扫描的,这样我们就知道了。