首页 > 解决方案 > Spring Boot 中的模块化 @Configuration/@Bean

问题描述

我正在制作一个基于微服务的项目,所以我的工作区中有更多的 Spring Boot 项目。我需要在其中一些配置restOperations,但我想为所有需要的项目配置一次。所以我试图将我的@Configuration类添加到一个 jar 中并导入到每个 MS 项目中。

问题是,当我在服务器中执行 MS 项目时,我收到此错误:

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

Description:

Field restOperations in com.epavanellio.base.business.controller.BusinessController required a bean of type 'org.springframework.web.client.RestOperations' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.springframework.web.client.RestOperations' in your configuration.

在这里,我有我的 Rest 配置类:

package com.epavanellio.base.restConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;

//@Component
@Configuration
public class SimpleRestConfiguration {
    
    final CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy())
            .build();
    
    @Bean
    public RestOperations createRestTemplate(final ClientHttpRequestFactory clientHttpRequestFactory){
        return new RestTemplate(clientHttpRequestFactory);
    }
    
    @Bean
    public ClientHttpRequestFactory createHttpRequestFactory (@Value("${rest.connect.timeout}") final int connectTimeout,
            @Value("${rest.read.timeout}") final int readTimeout) {
        
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(connectTimeout);
        clientHttpRequestFactory.setReadTimeout(readTimeout);
        clientHttpRequestFactory.setHttpClient(httpClient);
        
        return clientHttpRequestFactory;
    }
    
}

我在我的 MS 项目 POM 中导入了.jar (dpdc-rest)with类:SimpleRestConfiguration

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.epavanellio.base</groupId>
    <artifactId>ms-manager-business</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ms-manager-business</name>
    <description>Validate business logic. A microservice based project. </description>
    <packaging>war</packaging>
    
    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        
        <dependency>
            <groupId>com.epavanellio.base</groupId>
            <artifactId>domain</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>com.epavanellio.base</groupId>
            <artifactId>dpdc-rest</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>com.epavanellio.base</groupId>
            <artifactId>dpdc-custom-exception-handler</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
        </dependency>
        
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>3.0.0</version>
        </dependency>
     
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.el</artifactId>
            <version>2.2.6</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <finalName>ms-manager-business</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

在我的 MS 应用程序类中是这样的:

package com.epavanellio.base.business;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import com.epavanellio.base.restConfig.SimpleRestConfiguration;


//@SpringBootApplication(scanBasePackages={"com.epavanellio.base", "com.epavanellio.base.restConfig"})
//@Import(SimpleRestConfiguration.class)
//@ComponentScan({"com.epavanellio.base", "com.epavanellio.base.restConfig"})
@ComponentScan("com.epavanellio.base")
@EntityScan("com.epavanellio.base.domain")
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@SpringBootApplication
public class BusinessApplication extends SpringBootServletInitializer{
    

    public static void main(String[] args) {
        SpringApplication.run(BusinessApplication.class, args);
    }
    
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(BusinessApplication.class);
     }
}

正如你所看到的评论,我已经尝试让我的运行时以不同的方式“看到”我的配置类:首先我尝试(scanBasePackages={"com.epavanellio.base", "com.epavanellio.base.restConfig"})在我的 annotation 之后添加@SpringBootApplication,但发生了同样的错误。然后我尝试将SimpleRestConfiguration类包专门添加到@ComponentScan注释中(为此,我取消了类中的@Component注释SimpleRestConfiguration),但是发生了同样的错误。至少我尝试使用@Import,但在这种情况下我收到错误:

java.io.FileNotFoundException: class path resource [com/epavanellio/base/restConfig/SimpleRestConfiguration.class] cannot be opened because it does not exist 

有谁知道我怎样才能让我的应用程序类“看到”我的 @Configuration类?

标签: spring-bootmavenconfigurationmodularity

解决方案


问题是 Maven,由于某种原因,Maven 无法识别我的 jar。

所以我创建了一个新的依赖项目,具有新名称但相同的 SimpleRestConfiguration 类。我将新的 .Jar 导入到我的 MS 中,然后工作正常。

我的应用程序变成了这样:

@ComponentScan("com.epavanellio.base")
@EntityScan("com.epavanellio.base.domain")
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@SpringBootApplication
public class UserApplication extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
    
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(UserApplication.class);
     }
}  

推荐阅读