Davis
Davis

Reputation: 308

Spring AutoConfiguration manul import all components

I have the following autoconfigure class.

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({LoggerProviderProperties.class})
@Import({LoggerController.class, LogService.class, LogConfig.class})
public class ProviderAutoConfiguration {

}

I need to import all the components, services, configurations using @import annotation, otherwise for example, when I remove LogService.class (LogController autowires LogService) from @Import parameters, it throws the following error

Consider defining a bean of type 'com.log.LogService' in your configuration.

Do I really have to include all of them manuelly as shown above, or is there any other way to automatically detect classes annotated Service, Component or Configuration?

!This is starter library, not a executable app!

Upvotes: 0

Views: 1576

Answers (4)

Amit Kumar Sharma
Amit Kumar Sharma

Reputation: 46

If your components, services, configurations are under com.log as direct class or in sub-package, you can use @ComponentScan(basePackages="com.log.*")

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({LoggerProviderProperties.class})
@ComponentScan(basePackages="com.log.*")
public class ProviderAutoConfiguration {

}

Upvotes: 0

M. Deinum
M. Deinum

Reputation: 124516

The problem with your "library" is that it already needs a lot of moving parts, like Spring Data JPA, properly setup JPA. If that isn't available it will fail, or if you add @EnableJpaRepositories and/or things like @ComponentScan and @EntityScan it will (quite severely) interfere with the (auto)configuration of Spring Boot or the clients. Which is what you want to prevent.

Instead of all those annotations what you need to do is

  1. Conditionally enable @EnableJpaRepositories or just include the dependency and let the auto-configuration kick in (I suggest the latter)
  2. Don't add @ComponentScan, @EntityScan etc. instead use @AutoConfigurationPackage which is designed for starters.
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({LoggerProviderProperties.class})
@AutoConfigurationPackage
public class ProviderAutoConfiguration {

}

NOTE: This assumes that the ProviderAutoConfiguration is in the same or a higher package then your other classes. If not specify the basePackages in the @AutoConfigurationPackage.

Upvotes: 1

João Dias
João Dias

Reputation: 17460

Assuming you are using Spring Boot, at least so it seems according to your tags, you should take a look at @SpringBootApplication.

@SpringBootApplication encapsulates @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations with their default attributes. The default value for @ComponentScan means that all the sub packages on the package the @ComponentScan is used are scanned. That is why it is usually a good practice to include the main class in the base package of the project.

Upvotes: 0

eltabo
eltabo

Reputation: 3807

You can use @ComponentScan to specify the packages you want to scan to find configurations and/or components to load.

Upvotes: 0

Related Questions