Does #SpringBootApplication scans test folder for configurations? - spring

I've a #SpringBootApplication annotation in main class of my Spring Boot Application with ordinary folders structure (and #SpringBootApplication is one level package upper then beans in other packages)
I defined some #Configuration classes in some packages but under the test folder.
Will #SpringBootApplication autoconfigure it when start application?
Will #SpringBootApplication autoconfigure it when it will be finded by #SpringBootTest (it's also one level upper but in test folder) when test started?

I am not completely sure, but I would say no, #SpringBootApplication does not scan #Configuration classes in your test folder. What you should use instead is #TestConfiguration and then in your #SpringBootTest add #Import(YourTestConfiguration.class). Find an example below:
#TestConfiguration
public class YourTestConfiguration {
#Bean
(...)
}
#SpringBootTest
#Import(YourTestConfiguration.class)
class AppTests {
(...)
}
You can read more about this and check complete examples in the following online resources:
https://reflectoring.io/spring-boot-testconfiguration/
https://howtodoinjava.com/spring-boot2/testing/springboot-test-configuration/

Related

spring IoC: where to put ComponentScan

Here my spring configurer:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
#Slf4j
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
log.info("Web security performing");
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.cors().and()
.csrf().disable()
.authorizeRequests().anyRequest().permitAll();
log.info("Web security performed");
}
}
Nevertheless, it's never reached.
Here my application class:
#ComponentScan({
"cat.gencat.catsalut.hes.core.domain.mpi",
"cat.gencat.catsalut.hes.core.repository"
})
#SpringBootApplication(exclude = JmxAutoConfiguration.class)
public class ProjectApplication {
As you can see, #ComponentScan is placed on main ProjectApplication class.
I've realized that when I remove #ComponentScan from my main ProjectApplication class, my WebSecurityConfiguration is detected.
When it's present, WebSecurityConfiguration is ignored.
Any ideas?
SpringBootApplication without specifying #ComponentScan by default scan all classes in the current and those that are located in subpackages for picking Beans and Configuration and other stuffs. if you specify
#ComponentScan({
"cat.gencat.catsalut.hes.core.domain.mpi",
"cat.gencat.catsalut.hes.core.repository"
})
then only cat.gencat.catsalut.hes.core.domain.mpi and cat.gencat.catsalut.hes.core.repository and their subpackages will be scanned for beans. so try to put the class which contains #SpringBootApplication in the root of your project or use #SpringBootApplication(scanBasePackages = {'package1', 'package2'}) to specify packages that have to be scanned.
Try to rely on spring boot default conventions first:
Assuming you've placed ProjectApplication in the com.mycompany.myapp package
You can:
Remove the #ComponentScan annotation from it
Place WebSecurityConfiguration class in the same package com.mycompany.myapp or any package beneath it: Example: com.mycompany.myapp.web.security.config.
When spring boot application starts by default it has a very well defined policies of what should be scanned, so it scans the package of the application itself (the package where the file annotated with #SpringBootApplication resides) and the packages beneath it.
You can alter this behavior with #ComponentScan , but then you might have issues in spring boot driven tests. So without a reason I don't think you should really go there. Of course, if you have an actual reason of altering the default component scanning policies, please share so that our colleagues/me could try to come up with a solution.

#EnableAutoConfiguration on test context

I have project where I'm developing a spring auto configuration module.
I'm using a test configuration class (in test classpath),
In this class we are using #EnableAutoConfiguration
#Configuration
#EnableAutoConfiguration
public class MyTestContext {
}
In each of the test classes I'm using it the following way:
#ContextConfiguration(classes = {MyTestContext.class})
it looks like context is created correclty and test pass.
My Question is:
- Is it good practice to use #EnableAutoConfiguration on a test context ?
- what is the real effect of doing so ?

What will happen when I add multiple #ComponentScan in different #Configuration class

When using spring, I want to have a configuration structure like:
//package com.test
//main configuration A
#Configuration
#ComponentScan({"com.pakcage.A", "com.common"})
public class AppA{
...
}
//package com.test
//main configuration B
#Configuration
#ComponentScan({"com.pakcage.B", "com.common"})
public class AppB{
...
}
//package com.common
//sub configuration for common use
#Configuration
#ComponentScan({"com.pakcage.common1", "com.package.common2"})
public class CommonConfig{
...
}
I can launch my Application by useing Configuration AppA or Configuration AppB, and all of them contains some common packages to scan like
"com.pakcage.common1"/"com.package.common2"
, I want to put it into a single configuration.
I want to ask
What will happen when I put multiply #ComponentScan, there will be a combination of all of these #ComponenScan?
Is there some source code reference to read about how this happen?
Yes, all the packages defined by any #ComponentScan will be scanned.
Yes, spring framework is opensource. You can access the sources here.

#ContextConfiguration how to use XML based config and Java-based at same time?

I'm writing integration tests with SpringJUnit4. I got question. How in #ContextConfiguration I can use XML based config and Java-based at same time. As I know I couldn't do it, but maybe there exist backdoor?
Thanks in advance!
You could create static inner #Configuration class in your test class and use #ContextConfiguration annotation on your class without any parameters. As stated in the article below, Spring will automatically look for static inner #Configuration class if no XML locations or config classes are passed to the annotation.
You can then import your XML config and Java config classes using #Import and #ImportResource annotations. So your base class for your Spring tests could look something like this:
#ContextConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
public class BaseSpringTest {
#Configuration
#Import(BaseConfig.class)
#ImportResource({ "classpath:applicationContext-hibernate.xml" })
public static class ContextConfig {}
}
Sources
Testing with #Configuration Classes and Profiles
Import annotation JavaDoc
ImportResource annotation JavaDoc
Use #ImportResource on #Configuration class to import XML based config.

Is there a way to use Spring #Profile annotation at a package level?

I'm trying to put all my bean definitions for a specific profiles together, and would rather not push them all into one giant AppConfig.java class. I was wondering if there was a way to annotate at a package level using package-info.java and have all configuration files within that package inherit the profile.
I've tried the following in package-info.java:
#Profile("test")
package com.system.configuration.test;
import org.springframework.context.annotation.Profile;
But the #Configuration classes within the package seem to be used whether it is the "test" profile or not.
Is the only choice to annotate each class individually?
You can do it in different way by creating separate #Configuration classes for different profiles:
#Configuration
#Profile("test")
#ComponentScan("com.system.configuration.test")
public class TestProfile {
}
And then on your main configuration class you need to do imports:
#Configuration
#Import(TestProfile.class)
public class MainConfiguration {
}

Resources