Spring, annotation based, overriding of components

comdiv

When I setup Spring with XML a can override component definitions in XML files that are loaded later. It's very usefull for tests - I create default config set and than load it with addition test configuration that replaces some of components with specials (stubs, mocks, and so on). Now i start to migrate to annotation based configurations and it causes some problems.

The direct way to use annotations is auto-discovering of packages with @Component

So I have

@Configuration
@ComponentScan({"some.pack1", "some.pack2"})
public class ProductConfig{}

And when @Configuration @Import({ProductConfig.class}) @ComponentScan({"test.pack"}) public class TestConfig{}

But it will cause conflict if I try to override components in test.pack

And what I can do?

After some investigations where are 3 answers with some issues on them

  1. Worst - i can use @Filter on ComponentScan - it's worst way,
    • i must not import existed config (that can has some additional beans)
    • i must rescan all components, and explicitly define set of filters
  2. i can use @Profile and activeProfiles - it's better, while it's more sophistical, implict, but
    • it means that i must to know at product classes that they can be disabled in some tests
  3. not to use @ComponentScan on override Config and using @Bean insted of it
    • it's maybe well on test configurations, but it means that I lost ability to use @Component annotation
  4. use setParent on contexts - it works well, but
    • it's explicit operation on implementation of ApplicationContext not on interface
    • it's not hard to setup if overriding services has @Autwire dependency on some components from overriden config - require manual register and refresh

What is best and standard way to override conigurations??? When I used XML-based it was not a problem...

Vishal Nagpure

@profile plays a crucial role while implementing the testing strategy for your service/code.

For example, in development, you may have:

public interface DataSource{
 public String getHost();
}

Default implementation is

@Component
@Profile("Prod") 
public class DevDataSource implements DataSource {
    public String getHost(){
     // return actual value
}

And the implementation for component tests(Fake impl)

@Component
@Profile("test") 
public class StubbyDataSource implements DataSource {
    public String getHost(){
     return "some-host";   // return mocked data
}

Now you can write a test here which can act as integration test, unit test and component tests (https://martinfowler.com/bliki/ComponentTest.html)

In that way, your testing strategy would be much more elegant, concise and easy to maintain. Just by changing the profile, the same test can point to different environments (real or fake).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Spring annotation based caching

annotation based Spring bean validation

Annotation based Spring Activiti ProcessEngine

spring 5 MVC Annotation Based Application Not Working

Java annotation based Spring security config

FactoryBeans and the annotation-based configuration in Spring 3.0

Annotation based Auditing for spring-data-elasticsearch?

Spring WebMVC 5 - Annotation based Interceptor

Spring MVC xml based config to annotation

How to work with annotation based properties in Spring

Spring-Tiles annotation based configuration

Overriding spring bean based on bean id and primary attribute

Overriding beans in Java-based spring configuration hierarchy

How can I achieve annotation-based collection merging in Spring?

How to declare Transaction bean in spring in class based annotation?

Unable to acquire JDBC Connection in spring hibernate annotation based configuration

Pass a YAML-based property value to @Scheduled annotation in Spring Boot

Spring Annotation Configs - dynamically create classes based on YAML config

Implementing plugin architecture in annotation based Spring Boot Application

Spring annotation-based DI vs xml configuration?

Narrowing problem with Spring MVC annotation-based controller and @RequestMapping

Spring Annotation-based controllers not working if it is inside jar file

How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?

spring annotation-based configuration - memory consumption too high?

Status messages on the Spring MVC-based site (annotation controller)

Creating lazily initialized Spring beans using annotation based configuration

How to migrate spring annotation-based Hibernate code to Java EE

How to use @Inject annotation properly in spring Java based configuration?

Set context root for spring annotation based web app