0

As it says if I take out the @Lazy annotation my class won't get injected.

SomeClassTest

package com.somePackage;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.somePackage.SomeClass;

@Configuration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath*:junit-spring-context.xml") 
public class SomeClassTestTest {

    @Autowired 
        @Lazy     // If i take this out, the test fails 
    private SomeClass someClass; 

    @Test
    public void someTest() {
        assertNotNull(someClass);
    }   
}

SomeClass

package com.differentPackage;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.DependsOn;

@Service("someClass")
@DependsOn("someOtherClass")
public class SomeClass {
     // Bunch of code here 
}

SomeOtherClass

package com.someOtherPackage.config
import org.springframework.context.annotation.Configuration;

@Configuration
public class SomeOtherClass {
     // Just more code
}

junit-spring-context

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
     xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">




    <!-- Detect classes annotated with @Repository, @Component and @Service and register them as beans -->
    <context:component-scan base-package="com.differentPackage" />


</beans>

Why does it only work with @Lazy being present? Btw SomeClassTest and SomeClass are in different packages if that helps!

fit_dev
  • 7
  • 5
  • Please provide a [mcve]. – Sotirios Delimanolis Jul 23 '19 at 21:23
  • What's in the `junit-spring-context.xml` classpath configs? What does `SomeOtherClass` configure in addition to those configs? – Sotirios Delimanolis Jul 23 '19 at 22:09
  • SomeOtherClass is really company legacy code *lots of lines* but it has Value, Autowired and PostConstruct annotations – fit_dev Jul 23 '19 at 22:16
  • `@Configuration` beans are created before regular Spring beans are created, so the `SomeClass` beans hasn't been registered yet when `SomeClassTestTest` is initialized. You can only autowire in beans that are created by other `@Configuration` beans. See duplicate: [Autowire a bean within Spring's Java configuration](https://stackoverflow.com/q/28747743/5221149) --- Seems that `@Lazy` works, because that happens in later phases, where all the beans have now been created, but it's a hack. – Andreas Jul 23 '19 at 22:18
  • Since your classes don't create beans or otherwise do configuration, perhaps you meant to use `@Component` instead of `@Configuration`. Classes annotated with `@Configuration` have a very special purpose. – Andreas Jul 23 '19 at 22:21
  • You're right @Andreas, SomeClassTestTest should be **Component** annotation now that I think about it, but that still doesn't fix the Lazy annotation: I get a "no qualifying bean of type com.differentPackage.SomeClass" available: expected at least 1 bean which qualifies as autowire candidate. – fit_dev Jul 23 '19 at 22:30

1 Answers1

-1

Spring (by default) creates all beans with singleton scope in app context eagerly. That is the phylosophy of Spring framework. In your case, You have to create a bean, not at the application context startup, but when we request it. That is the reason why @Lazy is mandatory.