I have a prototype-scope bean, which I want to be injected by @Autowired annotation. In this bean, there is also @PostConstruct method which is not called by Spring and I don't understand why.
My bean definition:
package somepackage;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Scope("prototype")
public class SomeBean {
public SomeBean(String arg) {
System.out.println("Constructor called, arg: " + arg);
}
@PostConstruct
private void init() {
System.out.println("Post construct called");
}
}
JUnit class where I want to inject bean:
package somepackage;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath*:applicationContext-test.xml")
public class SomeBeanTest {
@Autowired
ApplicationContext ctx;
@Autowired
@Value("1")
private SomeBean someBean;
private SomeBean someBean2;
@Before
public void setUp() throws Exception {
someBean2 = ctx.getBean(SomeBean.class, "2");
}
@Test
public void test() {
System.out.println("test");
}
}
Spring configuration:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="somepackage"/>
</beans>
The output from execution:
Constructor called, arg: 1
Constructor called, arg: 2
Post construct called
test
When I initialize bean by calling getBean
from ApplicationContext
everything works as expected. My question is why injecting bean by @Autowire
and @Value
combination is not calling @PostConstruct
method
By default, Spring will not aware of the @PostConstruct and @PreDestroy annotation. To enable it, ...
– Garrote@PostConstruct
is called, just not in their expected case. – Squadron@Value
does not seem to be valid for autowired beans - for the second instance there is 'Creating instance of bean 'someBean'' message in the log, for the first - none. I suspect what Spring is doing in that case is converting the string value"1"
toSomeBean
using converters, never treating it as a bean. – Bowdlerize@Value
element is not a bean, it's not attached to the application context so lifecycle method is not called because there are no postprocessors it's a value-object created by converter. I see it as a bug that Spring allows you to annotated field both as@autowired
and@value
– Pampa