简体   繁体   中英

Spring Boot scanBasePackages unable to find beans from dependency

I have following:

@SpringBootApplication(scanBasePackages = {"com.my.package","com.my.package.mylibrary"})
@EnableAsync
@EnableSwagger2
@ServletComponentScan
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class})
public class MySpringBootApplication {....}

This application has package com.my.package , and it also has a library dependency containing spring beans I want to autowire in this application, and those beans are in package com.my.package.mylibrary inside library.

So I have put both for scanBasePackages . But Spring is not able to find beans from the library?

Edit:

From library, I have:

package com.my.package.mylibrary.repository;
....
public interface MyRepository extends JpaRepository<..., ....> {....}

In application, I have:

package com.my.package.controller;
....
@RestController
public class MyController {....}

MySpringBootApplication resides in com.my.package.

Error:

Exception in thread "main" java.lang.NoClassDefFoundError: com/my/package/mylibrary/repository/MyRepository
    at com.my.package.MySpringBootApplication.main(MySpringBootApplication.java:32)
Caused by: java.lang.ClassNotFoundException: com.my.package.mylibrary.repository.MyRepository
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

I added @EnableJpaRepositories for repository package. Now I see error related to entity MyEntity which MyRepository is based upon.

"java.lang.TypeNotPresentException: Type com.my.package.mylibrary.domain.MyEntity not present

So I added @EntityScan for "com.my.package.mylibrary.domain", but that makes application stuck infinitely.

First of all, you don't need to add scanBasePackages attribute in @SpringBootApplication as the base package is com.my.package .

If package is totally different, then you could have added it.

Spring Boot will automatically pick up the bean if the base package is same.

There is something called as separation of concerns that you should follow when you are writing code.


Update your MySpringBootApplication class to this:

@SpringBootApplication
@ServletComponentScan
public class MySpringBootApplication {....}

Create a separate config for asynchronous method execution.

 @Configuration
 @EnableAsync
 public class AsynchronousConfig {.....}

Create a separate config class for Swagger 2.

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {....}

Create separate config to exclude configuration.

@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, 
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
public class ExcludeConfigurationFile {....}

Note: Spring boot auto configuration will automatically pick up these @Configuration files

This should work.

You might want to scan the packages seperately and change your JpaRepository to CrudRepository. The configuration to seperate the layer is as follow.

@SpringBootApplication(scanBasePackages = {"com.my.package.controller"})
@EnableJpaRepositories(basePackages = {"com.my.package.mylibrary.repository"})
@EntityScan(basePackages = {"com.my.package.mylibrary.domain"})
public class MySpringBootApplication {

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM