How to override Spring @Autowire annotation and set null field?

I am a Spring neophyte who is working on a large Spring project that has an extensive relationship between Spring beans. I am trying to write some integration tests that perform subsets of the overall functionality of an application. For this, I would like to redefine some of them. For example, suppose I have a class

public class MyDataServiceImpl implements MyDataService { @Qualifier("notNeededForMyDataServiceTest") @Autowired private NotNeededForMyDataServiceTest notNeededForMyDataServiceTest; //... } 

and context file with:

 <bean id="myDataService" class="MyDataServiceImpl"> </bean> 

In my test, I do not need to use the notNeededForMyDataServiceTest field. Is there a way to override the @Autowired annotation and set notNeededForMyDataServiceTest to null, possibly in an XML file? I do not want to change any of the Java classes, but I want to avoid the (problematic) configuration of notNeededForMyDataServiceTest .

I tried to do:

 <bean id="myDataService" class="MyDataServiceImpl"> <property name="notNeededForMyDataServiceTest"><null/></property> </bean> 

This does not work. IntelliJ tells me: “Cannot resolve the“ notNeededForMyDataServiceTest ”property, apparently because there are no getters and setters for this field.

I am using Spring Framework 3.1.3.

+6
source share
3 answers

The following configuration should work, I allowed a mix in the Java configuration

 @Configuration //This will load your beans from whichever xml file you are using @ImportResource("classpath:/path/beans.xml") public class TestConfigLoader{ // This will declare the unused bean and inject MyDataServiceImpl with null. public @Bean(name="notNeededForMyDataServiceTest") NotNeededForMyDataServiceTest getNotNeededForMyDataServiceTest(){ return null; } ... any other configuration beans if required. } 

And annotate your test class as follows:

 // In your test class applicationContext will be loaded from TestConfigLoader @ContextConfiguration(classes = {TestConfigLoader.class}) public class MyTest { // class body... } 
+5
source

This can help:

and profiles:

You can create another beans definition in the XML configuration and then activate them with -Dspring.profiles.active="profile1,profile2" env.

+3
source

You are using the @Autowired mechanism incorrectly. The determinant is not a property that needs to be set. This is actually the name of the bean, so the container will be able to select one specific instance in case several beans of the same type are defined in the same context.

Thus, the container will look for a bean of type NotNeededForMyDataServiceTest and name (actually it will be a bean id in XML): NotNeededForMyDataServiceTest .

I want you to indicate that the container does not enter anything into this field unless a bean of type NotNeededForMyDataServiceTest is specified in the application context. This can be achieved simply by setting the required annotation attribute to false :

 @Autowired(required = false) NotNeededForMyDataServiceTest someOptionalDependency; 

The only drawback of this approach would be that the container will never complain at runtime if there is nothing to enter in this field (and you may need this health check when your code works).


If you do not want this dependency to be optional (or you cannot edit this code for any reason), you need to specify the mock / null value for this field, indicating this explicitly in your context. One option to do this is to use the Java configuration instead of XML (for example, in @Abe's answer), and another approach is to use a factory bean that returns null (for example, in this question ).

+3
source

Source: https://habr.com/ru/post/950297/


All Articles