Spring 3.0 injection null after initalization
-
14-11-2019 - |
Question
I am trying to inject the datasource object into a servlet. I have the logger to print in the set method. It works ok on pre-inialization. But when I request the servlet it gives me nullPointerException.
Any suggestion on why this happen? (I don't think this related to the servlet I am extending)
Here is the applicationContext.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="dataServlet" class="com.mycom.util.DataServlet">
<property name="dataSource" ref="dataSource" />
<property name="test" value="dataSource" />
</bean>
The servlet
public class DataServlet extends DataSourceServlet {
...
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
logger.log(Level.INFO, "Inj: datasrc");
}
@Autowired
public void setTest(String test) {
this.test = test;
logger.log(Level.INFO, "Set Test {0}", this.test);
}
}
I set break point @ the setTest, it breaks @ pre-init. but when the actual object being request. It is doesn't break @ the setTest.
Why is it so? (singleton/ scope issue related?)
Please advise! Thanks in advance!
Solution
You have two instances of your servlet:
- one managed by Spring, which has
DataSource
injected properly - second one created by Tomcat, that knows nothing about Spring (and doesn't have the
DataSource
)
Actually if you would use @Resource
instead of @Autowired
Tomcat (tested on 7.0) will scream that DataSource
is not bound to JNDI (which proves it is the servlet container that managed the servlet lifecycle).
Your problem is that you want to inject Spring beans to an object that is completely out of Spring control. There are several workarounds for this problem:
DispatcherServlet
and Spring MVCHttpRequestHandlerServlet
to dispatch all requests to handling Spring beanWebApplicationContextUtils
and fetch beans manually (nasty solution)
If you don't want to dive into MVC, I would suggest HttpRequestHandlerServlet
. Here: 1, 2 is an example (should also work with Servlet prior 3.0)