【问题标题】:How to autowire a component in a dependency/external jar in Spring? [duplicate]如何在 Spring 的依赖项/外部 jar 中自动装配组件? [复制]
【发布时间】:2019-06-14 00:00:34
【问题描述】:

我有一个 Spring Boot 项目,我无法从 外部 jar 中获取要自动装配的组件。当我尝试这样做时,我收到了 org.springframework.beans.factory.NoSuchBeanDefinitionException 说找不到具有该名称的 bean。

我尝试了一些在类似问题中找到的解决方案,例如:

How to autowire @service from external Jar in Spring

Spring Boot @autowired does not work, classes in different package

How can I @Autowire a spring bean that was created from an external jar?

..但仍然无法使其正常工作。

这是我想要完成的一个示例:

这里是Spring Boot项目中的boot class spring-project-example

package com.springdi.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import com.dependency.example.DependencyBasePackageClass;
import com.dependency.example.somepackage.SomeBean;

@SpringBootApplication
@ComponentScan(basePackages = {"com.springdi.example"}, basePackageClasses = DependencyBasePackageClass.class)
public class SpringProjectExampleApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringProjectExampleApplication.class, args);

        String beanName = SomeBean.class.getName();
        System.out.printf("%s can be autowired: %s\n", beanName, String.valueOf(context.containsBean(beanName)).toUpperCase());
    }
}

这只是一个简单的 Spring Boot 项目,检查是否可以自动装配依赖项 jar 中存在的组件。

这是jar中的组件(dependency-example-1.0.0.jar)

package com.dependency.example.somepackage;

import org.springframework.stereotype.Component;

@Component
public class SomeBean {

    public void someMethod() {
        System.out.println("Some process...");
    }
}

这是同一个jar基础包类

package com.dependency.example;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Just a class to serve as the root for component
 * scanning in "com.dependency.example" and its sub-packages
 */
@Configuration
@ComponentScan
public class DependencyBasePackageClass {

}

我已经在 SpringProjectExampleApplication 和 @ComponentScan 中尝试过 @Import(DependencyBasePackageClass.class)basePackagesbasePackageClasses,但没有成功。

我也尝试过使用@SpringBootApplication(scanBasePackageClasses = {SpringProjectExampleApplication.class, DependencyBasePackageClass.class})

还有不安全的@SpringBootApplication(scanBasePackages = {"com.springdi.example", "com.dependency.example"})

@Configuration @ComponentScan({"com.dependency.example"}) 也失败,context.containsBean("com.dependency.example.somepackage.SomeBean") 仍然返回 false

这个 jar 包含在类路径和 pom.xml 中作为依赖项

<dependencies>
    <!-- other dependencies -->

    <dependency>
        <groupId>com.rbaggio</groupId>
        <artifactId>dependency-example</artifactId>
        <version>1.0.0</version>
        <scope>system</scope>
        <systemPath>${basedir}/lib/dependency-example-1.0.0.jar</systemPath>
    </dependency>
</dependencies>

可能是 jar 的位置、包含方式还是需要一些额外的配置?

如果有任何帮助,我将不胜感激!提前致谢。

【问题讨论】:

  • @ComponentScan 阻碍了找到该依赖 bean。执行@Import 或创建一个返回依赖项目的bean。

标签: java spring maven spring-boot


【解决方案1】:

好吧,一些基本的东西,你把你的包弄混了一点。

@SpringBootApplication 将扫描所有在该类下面的包中的类。此注解是@EnableAutoConfiguration@Configuration@ComponentScan 的别名,表示@ComponentScan(basePackages = {"com.springdi.example"}, basePackageClasses = DependencyBasePackageClass.class)不需要

com.springdi.example     // class with @SpringBootApplication annotation
         |
         |
         |
com.springdi.example.*    // Will find all @Service, @Component, @Configuration
                          // in subpackages below the @SpringBootApplication 
                          // annotation

你可以在这里SpringBootApplication阅读更多关于注解的信息

由于您的其他带注释的类@SpringBootApplication 在同一包结构中,因此您需要定义要扫描注释的所有位置。

@SpringBootApplication(scanBasePackages = {"com.springdi.example", "com.dependency.example"})

可能会包含您要扫描的所有包。

【讨论】:

  • 我也试过这个,但没有成功... applicationContext.containsBean("com.dependency.example.somepackage.SomeBean") 仍然返回false。我认为问题可能是 jar 包含在类路径中的方式或缺少一些注释。无论如何,谢谢。
  • 您需要删除 DependencyBasePackageClass 中的第二个 @ComponentScan
  • 仍然不起作用..但是如果我给 SomeBean 起一个名字,比如 @Component("someBean") ,它就会起作用。看来我必须为包含的 jar 中的每个 bean 命名,以便通过 @Autowired 使用它们
  • 你可以用它来列出所有加载的bean stackoverflow.com/questions/33348937/…
  • 它也有效。列出所有加载的 bean 会很有帮助。谢谢托马斯! (我会接受你上面的回答)
猜你喜欢
  • 2014-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多