Java 运行jar时找不到RestTemplate

Java 运行jar时找不到RestTemplate,java,spring-boot,gradle,Java,Spring Boot,Gradle,我的项目结构: demo common demo-consumer demo有两个模块,通常作为jar包提供给其他模块,demo是一个空项目 demo build.gradle plugins { id 'org.springframework.boot' version '2.3.8.RELEASE' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } g

我的项目结构:

demo
    common
    demo-consumer
demo有两个模块,通常作为jar包提供给其他模块,demo是一个空项目

demo build.gradle

plugins {
    id 'org.springframework.boot' version '2.3.8.RELEASE'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

allprojects {
    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'


    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }

    repositories {
        mavenLocal()
        mavenCentral()
    }

    ext {
        set('springCloudVersion', "Hoxton.SR9")
    }

    dependencies {

        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'org.springframework.boot:spring-boot-starter-web-services'
        compileOnly 'org.projectlombok:lombok'
        developmentOnly 'org.springframework.boot:spring-boot-devtools'
        runtimeOnly 'mysql:mysql-connector-java'
        annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
        }
    }

    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }

    test {
        useJUnitPlatform()
    }
}
演示设置.gradke

rootProject.name = 'demo'
include 'common'
include 'demo-consumer'
模块通用项目结构:

src
  main
    java
     com.example.common
      config
       RestTemplateConfig.class
      App.class


My RestTemplateConfig.class:

package com.example.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}


My App.class:

package com.example.common;

public class App {

    public static void main(String[] args) {

    }
}
模块演示消费者项目结构,一个简单的spring boot应用程序:

src
  main
    java
     com.example.democonsumer
      controller
       TestController.class
     DemoConsumerApplication.class


My TestController.class:
    package com.example.democonsumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/test0")
    public String test0(){
        return "Success";
    }

    @GetMapping("/test1")
    public String test1(){
        return restTemplate.getForObject("http://localhost:9999/test0", String.class);
    }
}

My DemoConsumerApplication.class:

package com.example.democonsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.example"})
public class DemoConsumerApplication {

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

demo-consumer's build.gradle:
dependencies {
    implementation project(":common")
}
我先构建common,然后由gradle构建demo-consumer,将demo-consumer.jar放在服务器上; 运行jar包,它失败了

2021-01-20 11:24:17.463  INFO 4007 --- [           main] c.e.d.DemoConsumerApplication            : Starting DemoConsumerApplication on iZ2ze9tlmbs6w25xr1jp92Z with PID 4007 (/home/spring-cloud-template/demo-consumer.jar started by root in /home/spring-cloud-template)
2021-01-20 11:24:17.467  INFO 4007 --- [           main] c.e.d.DemoConsumerApplication            : No active profile set, falling back to default profiles: default
2021-01-20 11:24:19.555  INFO 4007 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$4d8ad8fc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2021-01-20 11:24:19.740  INFO 4007 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
2021-01-20 11:24:20.545  INFO 4007 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9990 (http)
2021-01-20 11:24:20.578  INFO 4007 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-01-20 11:24:20.579  INFO 4007 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-20 11:24:20.746  INFO 4007 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-01-20 11:24:20.750  INFO 4007 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3169 ms
2021-01-20 11:24:21.410  WARN 4007 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testController': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2021-01-20 11:24:21.417  INFO 4007 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-01-20 11:24:21.468  INFO 4007 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-20 11:24:21.806 ERROR 4007 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Field restTemplate in com.example.democonsumer.controller.TestController required a bean of type 'org.springframework.web.client.RestTemplate' 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.RestTemplate' in your configuration.


Idea正常运行,jar包失败,如何修复?

尝试以这种方式注入
RestTemplate


RestTemplateConfig

@Bean
公共clienthtprequestfactory clienthtprequestfactory(){
SimpleClientHttpRequestFactory SimpleClientHttpRequestFactory=新SimpleClientHttpRequestFactory();
ClientHttpRequestFactory ClientHttpRequestFactory=新缓冲ClientHttpRequestFactory(simpleClientHttpRequestFactory);
返回客户前传工厂;
}
@豆子
公共RestTemplate RestTemplate(ClientHttpRequestFactory ClientHttpRequestFactory){
RestTemplate RestTemplate=新的RestTemplate(clientHttpRequestFactory);
返回REST模板;
}

@Autowired
私人RestTemplateBuilder;
//使用RestTemplateBuilder实例化RestTemplate对象,spring默认注入了RestTemplateBuilder实例
@豆子
公共RestTemplate RestTemplate(){
返回builder.build();
}

请打开整个错误日志。已编辑,打开整个错误日志尝试向您添加
@ComponentScan(basePackages={“com.example.common”}
。我不确定你的公共配置组件是否从你的演示消费者那里获得。你的公共项目不应该应用spring启动插件。应用插件时,jar的结构将与普通jar不同,并且类将不可用。当然,在中也解释了这一点。我解决了这个问题;在demo consumer中更改build.gradle;实施项目(“:common”)==>编译项目(“:common”);构建并运行jar,;没关系。但是为什么?谢谢,但不起作用,错误:组件需要一个类型为“org.springframework.web.client.restemplate”的bean,但找不到。这没有帮助。问题是生成了两个spring引导项目,由于结构上的差异,您不能使用spring引导构建jar作为依赖项。