GVKun编程网logo

java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件(springboot扫描外部jar)

9

如果您对java–在SpringBoot应用程序中扫描不同maven模块/JAR的组件感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于java–在SpringBoot应用程序

如果您对java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件的详细内容,我们还将为您解答springboot扫描外部jar的相关问题,并且为您提供关于java – spring-boot应用程序无法启动、java – 在SpringBoot应用程序启动时捕获Hibernate异常?、java – 在没有Spring Boot应用程序的情况下使用Spring Boot Actuator、java – 测试启动Spring-boot应用程序的有价值信息。

本文目录一览:

java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件(springboot扫描外部jar)

java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件(springboot扫描外部jar)

我有两个Maven模块.
第一个名为“application”,包含仅包含以下行的Spring引导应用程序类:

package org.example.application;

@SpringBootApplication
@ComponentScan({"org.example.model","org.example"})
public class Application {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class,args);
    }
}

在同一个Maven模块和包org.example.application中,我有一个使用Component的RestController,而Component又使用下面描述的另一个Maven模块的组件.

另一个名为“model”的Maven模块包含spring引导组件(crud-repositories,实体等).所有这些类都与第一个Maven模块(org.example)在相同的包结构下,但在其子包中,如org.example.model.entities,org.example.model.repositories等.

所以,流程是这样的:

包org.example中的Maven模块应用程序:
SpringBootApplication – > RestController – >为MyComponent

应该在MyComponent中自动装配的组件是包org.example.model下的模型Maven模块中的组件.

但是当我启动应用程序时,我只是得到错误:

***************************
APPLICATION Failed TO START
***************************

Description:

Field myRepository in org.example.MyComponent required a bean of type 'org.example.model.repositories.MyRepository' that Could not be found.

Action:

Consider defining a bean of type 'org.example.model.repositories.MyRepository' in your configuration.

org.example.model.repositories.MyRepository确实存在于Maven模块“model”中,但是SpringBootApplication类找不到它!

如您所见,我尝试将扫描组件明确定义为:
@ComponentScan({“org.example.model”,“org.example”})但这似乎没有帮助.

那我做错了什么?

最佳答案
你应该想知道的第一件事是:为什么你声明@ComponentScan而@SpringBootApplication的目标之一是(除其他事项外)启用组件扫描?
从Spring Boot documentation开始:

The @SpringBootApplication annotation is equivalent to using
@Configuration,@EnableAutoConfiguration and @ComponentScan with their
default attributes

请注意,在Spring Boot Application的类上,声明@ComponentScan将值指定为basePackages,它会覆盖默认情况下由@SpringBootApplication使用的basePackages,它是类所在的当前包.因此,要将Spring Boot Application类的包和缺少的其他包作为基础包,您必须明确设置它们.

除了basePackages是递归的.因此,要为位于“org.example”和“org.example.model”包中的类启用扫描,指定“org.example”就足够了,因为“org.example.model”是它的子包.

试试看:

@SpringBootApplication(scanBasePackages={"org.example"})

或者:

@SpringBootApplication
@ComponentScan("org.example")

在Spring Boot应用程序中指定@ EnableJpaRepositories / @ ComponentScan / scanBasePackages?

在设计Spring Boot应用程序布局时,您有两种情况:

1)case(赞成)你使用一个包布局,它提供Spring Boot的零配置自动配置.

总结一下:如果您的类使用Spring Bean构造型注释:@ Component,@ Storage,@ Repositories,…位于Spring Boot Application类的相同包或子包中,仅声明
@SpringBootApplication就是您所需要的.

2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置.

它通常意味着您有要扫描的候选类,这些类不在使用@SpringBootApplication注释的类的包(或子包)中.
在这种情况下,您可以添加scanBasePackages属性或添加@ComponentScan以指定要扫描的包.
但另外,如果您的存储库不在使用@SpringBootApplication注释的类的包或子包中,则必须声明其他内容,例如:@EnableJpaRepositories(=“packageWhereMyRepoAreLocated”)

关于这部分的Here is the documentation(重点是我的):

80.3 Use Spring Data Repositories

Spring Data can create implementations of @Repository interfaces of
varIoUs flavors. Spring Boot handles all of that for you,as long as
those @Repositories are included in the same package (or a
sub-package) of your @EnableAutoConfiguration class.

For many applications,all you need is to put the right Spring Data
dependencies on your classpath (there is a
spring-boot-starter-data-jpa for JPA and a
spring-boot-starter-data-mongodb for Mongodb) and create some
repository interfaces to handle your @Entity objects. Examples are in
the JPA sample and the Mongodb sample.

Spring Boot tries to guess the location of your @Repository
deFinitions,based on the @EnableAutoConfiguration it finds. To get
more control,use the @EnableJpaRepositories annotation (from Spring
Data JPA).

例子

1)case(赞成)你使用一个包布局,它提供Spring Boot的零配置自动配置.

使用在org.example包中声明的Spring Boot应用程序,以及在同一个包或org.example的子包中声明的所有bean类(包含的存储库),以下声明对于Spring Boot应用程序来说已经足够了:

package org.example;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class,args);
    }
}

存储库可以位于org.example.repository包中,例如:

package org.example.repository;

@Repository
public interface FooRepository extends  JpaRepository

package org.example.repository;

@Repository
public interface BarRepository extends  JpaRepository

控制器可以位于org.example.controller包中:

package org.example.controller;

@RestController
@RequestMapping("/api/foos")
public class FooController  {...}

等……

2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置.

使用org.example.application包中声明的Spring Boot应用程序,而不是在同一个包或org.example.application的子包中声明的所有bean类(包含的存储库),Spring将需要以下声明:启动应用:

package org.example.application;

@SpringBootApplication(scanBasePackages= {
                      "org.example","org.thirdparty.repository"})
@EnableJpaRepositories("org.thirdparty.repository")
public class Application {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class,args);
    }
}

bean类可以如下所示.

可能来自外部JAR的存储库可以位于org.thirdparty.repository包中,例如:

package org.thirdparty.repository;

@Repository
public interface FooRepository extends  JpaRepository

package org.thirdparty.repository;

@Repository
public interface BarRepository extends  JpaRepository

控制器可以位于org.example.controller包中:

package org.example.controller

@RestController
@RequestMapping("/api/foos")
public class FooController  {...}

等……

结束语:我们鼓励在命名空间的基础包中定义Spring Boot应用程序,以使Spring Boot配置尽可能简单.

java – spring-boot应用程序无法启动

java – spring-boot应用程序无法启动

我最近开始使用 spring-boot开发一个web应用程序,anf,按照官方网站上的指南,设法创建这两个文件:

的pom.xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>spring</groupId>
  <artifactId>app</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>app</name>
  <url>http://maven.apache.org</url>

  <properties>
    <start-class>com.spring.app.Application</start-class>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

Application.java

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class,args);

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDeFinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }

}

但是当我尝试用java -jar appname运行应用程序时,我得到错误:找不到主类:com.spring.app.Application.程序将退出,并在终端:线程“main”中的异常java.lang.NoClassDefFoundError:com / spring / app / Application.

我做错了什么?

解决方法

你的pom.xml中有2件事要做.

首先将start-class更改为您的应用程序类.
第二,将超酷的Spring Boot maven builder添加到你的pom中.

像这样的东西:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.sample</groupId>
<artifactId>beanlist</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
    <start-class>com.sample.Application</start-class>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.8.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project

然后使用“mvn install”创建你的jar.你的代码运行得很好.

java – 在SpringBoot应用程序启动时捕获Hibernate异常?

java – 在SpringBoot应用程序启动时捕获Hibernate异常?

我正在尝试使用 Spring Boot 1.2.6和HibernateJpaAutoConfiguration.它很棒;这就是它“神奇地”由entityManager创建,并使用我的spring.jpa.*属性为我开箱即用.

但是,在数据库错误(凭据无效,数据库无法访问等)的情况下,我找不到一种在启动时捕获Hibernate异常的简洁方法.

我想我可以捕获所有BeanCreationException并检查根本原因,但这似乎是一个非常黑客:

ConfigurableApplicationContext context;
    try {
        SpringApplication app = new SpringApplication(Application.class);
        context = app.run(args);
    } catch (Exception e) {
        // check if it is a DB error.  
        if( ExceptionUtils.getRootCause(e) instanceof( HibernateException ) ){
            System.out.println( "You are having trouble with the DB: " + ExceptionUtils.getRootCauseMessage(e) );
        }
    }
    finally{
        // finished so close the context
        if( context != null )
            context.close();
    }

在不失去使用自动配置的能力的情况下,是否有更干净/更简洁的方法?另外,如果没有解析错误消息,有没有办法确定Hibernate / DB错误是什么(即:无效的信用证,未经验证的数据库等).

解决方法

您可以尝试捕获JDBCConnectionException,而不是捕获非常通用的HibernateException.这是用于数据库连接问题的HibernateException的子类(包括不正确的数据库设置).

https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/exception/JDBCConnectionException.html

java – 在没有Spring Boot应用程序的情况下使用Spring Boot Actuator

java – 在没有Spring Boot应用程序的情况下使用Spring Boot Actuator

具有生产信息端点的 Spring Boot的Actuator库对任何服务器应用程序都非常有用.但问题是我找不到集成到传统Spring应用程序(不是Spring BOOT应用程序)的方法.

必须有一些方法来使用执行器的端点,但我无法将它们连接起来.

我有一个JavaConfig类,如下所示

@Configuration
@ComponentScan(basePackages = { "com.company.helper","org.springframework.boot" })
@EnableWebMvc
@Import({ DbConfig.class })

public class AppConfig extends WebMvcConfigurerAdapter {

}

但是此配置在部署期间会引发错误.

没有Spring Boot应用程序可以完成这种连线吗?

解决方法

我在此博客文章中添加了有关如何在非启动应用程序中添加spring boot执行器的信息

http://givenwhenthen.blogspot.com/2015/09/adding-spring-boot-actuator-to-non.html

在应用程序的build.gradle中,我添加了以下依赖项

compile('org.springframework.boot:spring-boot-actuator:1.2.5.RELEASE'){
    exclude group: 'org.springframework.boot',module:'spring-boot-starter-logging'}

在应用程序的Spring Config类中,我添加了以下内容:

import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;  
 import org.springframework.boot.actuate.endpoint.BeansEndpoint;  
 import org.springframework.boot.actuate.endpoint.HealthEndpoint;  
 import org.springframework.boot.actuate.endpoint.InfoEndpoint;  
 import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;  
 import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;  
 import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;  
 import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;  
 import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;  

 @Configuration  
 @Import(EndpointAutoConfiguration.class)  
 public class MyAppSpringConfig {  

   @Bean  
   @Autowired  
   //Define the HandlerMapping similar to RequestHandlerMapping to expose the endpoint  
   public EndpointHandlerMapping endpointHandlerMapping(  
     Collection<? extends MvcEndpoint> endpoints  
   ){  
     return new EndpointHandlerMapping(endpoints);  
   }  

   @Bean  
   @Autowired  
   //define the HealthPoint endpoint  
   public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate){  
     return new HealthMvcEndpoint(delegate,false);  
   }  

   @Bean  
   @Autowired  
   //define the Info endpoint  
   public EndpointMvcAdapter infoMvcEndPoint(InfoEndpoint delegate){  
      return new EndpointMvcAdapter(delegate);  
   }  

   @Bean  
   @Autowired  
   //define the beans endpoint  
   public EndpointMvcAdapter beansEndPoint(BeansEndpoint delegate){  
     return new EndpointMvcAdapter(delegate);  
   }  

   @Bean  
   @Autowired  
   //define the mappings endpoint  
   public EndpointMvcAdapter requestMappingEndPoint(  
     RequestMappingEndpoint delegate  
   ){  
     return new EndpointMvcAdapter(delegate);  
  }  
}

如果你想摆脱一个额外的依赖,那么请参阅博客帖子.

UPDATE

此外,您需要确保为RequestMappingHandlerAdapter定义了一个bean,如果您没有它,Servletdispatcher将无法为您的HealthMvcEndpoint的处理程序获取适配器.

如果你没有它只是将它添加到你的bean配置文件

xml配置:

<bean>
        <property name="messageConverters">
            <list>
                <ref bean="jsonConverter"/>
            </list>
        </property>
    </bean>

    <bean id="jsonConverter">
        <property name="supportedMediaTypes" value="application/json" />
        <property name="prettyPrint" value="true" />
    </bean>

java – 测试启动Spring-boot应用程序

java – 测试启动Spring-boot应用程序

我有一个JUnit测试,在测试后启动一个 spring-boot应用程序(在我的例子中,主类是 SpringTestDemoApp):

@WebIntegrationTest
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringTestDemoApp.class)
public class SpringTest {

    @Test
    public void test() {
        // Test http://localhost:8080/ (with Selenium)
    }
}

使用spring-boot 1.3.3.RELEASE一切正常.尽管如此,注释@WebIntegrationTest和@SpringApplicationConfiguration已在spring-boot 1.5.2.RELEASE中删除.我试图将代码重构为新版本,但我无法做到.通过以下测试,我的应用程序在测试之前未启动,http://localhost:8080返回404:

@RunWith(springrunner.class)
@SpringBoottest(classes = SpringTestDemoApp.class)
@WebAppConfiguration
public class SpringTest {

    @Test
    public void test() {
        // The same test than before
    }

}

如何重构我的测试以使其在spring-boot 1.5中工作?

解决方法

@SpringBoottest中的webEnvironment选项非常重要.它可以采用NONE,MOCK,RANDOM_PORT,DEFINED_PORT等值.

> NONE只会创建spring bean而不是任何模拟servlet环境.
> MOCK将创建spring bean和模拟servlet环境.
> RANDOM_PORT将在随机端口上启动实际的servlet容器;这可以使用@LocalServerPort自动装配.
> DEFINED_PORT将获取属性中定义的端口并使用它启动服务器.

如果未定义任何webEnvironment,则默认值为RANDOM_PORT.所以应用程序可能会在不同的端口为您启动.

尝试将其覆盖为DEFINED_PORT,或尝试自动装配端口号并尝试在该端口上运行测试.

关于java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件springboot扫描外部jar的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于java – spring-boot应用程序无法启动、java – 在SpringBoot应用程序启动时捕获Hibernate异常?、java – 在没有Spring Boot应用程序的情况下使用Spring Boot Actuator、java – 测试启动Spring-boot应用程序等相关内容,可以在本站寻找。

本文标签: