如何在 Spring 的依赖项/外部 jar 中自动装配组件? [英] How to autowire a component in a dependency/external jar in Spring?

查看:77
本文介绍了如何在 Spring 的依赖项/外部 jar 中自动装配组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

package com.springdi.example;导入 org.springframework.boot.SpringApplication;导入 org.springframework.boot.autoconfigure.SpringBootApplication;导入 org.springframework.context.ConfigurableApplicationContext;导入 org.springframework.context.annotation.ComponentScan;导入 com.dependency.example.DependencyBasePackageClass;导入 com.dependency.example.somepackage.SomeBean;@SpringBootApplication@ComponentScan(basePackages = {"com.springdi.example"}, basePackageClasses = DependencyBasePackageClass.class)公共类 SpringProjectExampleApplication {公共静态无效主(字符串 [] args){ConfigurableApplicationContext context = SpringApplication.run(SpringProjectExampleApplication.class, args);String beanName = SomeBean.class.getName();System.out.printf("%s 可以自动装配:%s\n", beanName, String.valueOf(context.containsBean(beanName)).toUpperCase());}}

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

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

package com.dependency.example.somepackage;导入 org.springframework.stereotype.Component;@组件公共类 SomeBean {公共无效一些方法(){System.out.println("一些进程...");}}

这是同一个jar

基本包类

package com.dependency.example;导入 org.springframework.context.annotation.ComponentScan;导入 org.springframework.context.annotation.Configuration;/*** 只是一个作为组件根的类* 扫描com.dependency.example"及其子包*/@配置@ComponentScan公共类 DependencyBasePackageClass {}

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

我也尝试使用 @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 作为依赖包含在 classpath 和 pom.xml 中

<!-- 其他依赖项--><依赖><groupId>com.rbaggio</groupId><artifactId>依赖示例</artifactId><version>1.0.0</version><范围>系统</范围><systemPath>${basedir}/lib/dependency-example-1.0.0.jar</systemPath></依赖></依赖项>

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

我很感激任何帮助!提前致谢.

解决方案

好的,一些基本的东西,你的包有点混淆了.

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

com.springdi.example//带有@SpringBootApplication 注解的类|||com.springdi.example.*//会找到所有@Service、@Component、@Configuration//在@SpringBootApplication 下面的子包中//注释

您可以在此处阅读有关注释的更多信息 SpringBootApplication

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

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

可能会包含您要扫描的所有软件包.

I have a Spring Boot project and I can't get components from an external jar to be autowired. When I try to, I got a org.springframework.beans.factory.NoSuchBeanDefinitionException saying that can't find a bean with that name available.

I tried some solutions found in similar questions, like these ones:

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?

..but still can't managed it to work.

Here is an example of what I'm trying to accomplish:

Here is boot class in the Spring Boot project 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());
    }
}

It's just a simple Spring Boot project checking if it is possible to autowire a component present in the dependency jar.

Here is the component in the 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...");
    }
}

And here is the base package class of this same 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 {

}

I've already tried @Import(DependencyBasePackageClass.class) in SpringProjectExampleApplication and @ComponentScan with basePackages and basePackageClasses, but no success.

I also tried using @SpringBootApplication(scanBasePackageClasses = {SpringProjectExampleApplication.class, DependencyBasePackageClass.class})

and the not type safe @SpringBootApplication(scanBasePackages = {"com.springdi.example", "com.dependency.example"}).

@Configuration @ComponentScan({"com.dependency.example"}) also fails, context.containsBean("com.dependency.example.somepackage.SomeBean") still returns false.

This jar is included in classpath and in the pom.xml as a dependency

<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>

Could it be the location of the jar, the way it is included or some extra configuration needed?

I'd appreciate any help! Thanks in advance.

解决方案

Okey some basic things, you have mixed up your packages a bit.

@SpringBootApplication will scan all classes in packages below the class this is annotated on. This annotation is an alias for @EnableAutoConfiguration, @Configuration and @ComponentScan means that @ComponentScan(basePackages = {"com.springdi.example"}, basePackageClasses = DependencyBasePackageClass.class) is not needed.

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

You can read more about the annotation here SpringBootApplication

Since your other annotated classes are NOT in the same package structure as the @SpringBootApplication you need to define all the places you want to scan for annotations.

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

will probably include all the packages that you want to scan through.

这篇关于如何在 Spring 的依赖项/外部 jar 中自动装配组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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