一直以为,我都是一个很能复制代码的人,把别人的代码从一个地方搬到另外一个地方并且能跑起来似乎是我很容易就能办到的事情,但是昨天晚上出了点意外。
Spring的依赖注入我想大家都很熟悉了,不外乎是在WebApplicationContext的环境中定义一大堆bean,然后写清楚它们的依赖引用关系和值的关系,就这样,一个利用配置就可以实现bean关系结构就出来了,就是这么一个简单的配置,我却搞了几个小时,原因是什么呢?
先来给大家看看我的代码配置:
首先定义Spring的contextConfigLocation的读取xml文件是spring-context.xml,在这个文件中指明了一些数据库连接的文件和一些数据源的信息,还有一些bean的依赖关系。由于我采用的是一般大家使用的三层结构,所以还还应该给controller定义一些dao的依赖实现,这部分的spring-context.xml的代码如下:
<bean id="demoDaoImpl" class="com.springdemo.dao.DemoDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="dispatchCtrl" class="com.springdemo.controller.DispatchCtrl">
<property name="demoDao">
<ref bean="demoDaoImpl"/>
</property>
</bean>
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="dispatchCtrl" class="com.springdemo.controller.DispatchCtrl">
<property name="demoDao">
<ref bean="demoDaoImpl"/>
</property>
</bean>
定义一个servlet的名称为dispatch,则dispatch-servlet.xml的部分代码如下:
<bean id="handlerMapping"
class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="defaultHandler" ref="dispatchController"/>
</bean>
<bean id="dispatchController" class="com.abchina.springdemo.controller.DispatchCtrl">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/process">process</prop>
</props>
</property>
</bean>
</property>
</bean>
class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="defaultHandler" ref="dispatchController"/>
</bean>
<bean id="dispatchController" class="com.abchina.springdemo.controller.DispatchCtrl">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/process">process</prop>
</props>
</property>
</bean>
</property>
</bean>
DispatchCtrl类的简单实现如下:
public class DispatchCtrl extends MultiActionController ...
{
private DemoDao demoDao;
public void setDemoDao(DemoDao demoDao) ...{
this.demoDao = demoDao;
}
public ModelAndView index(HttpServletRequest request, HttpServletResponse response) ...{
String des = "";
Map map = new HashMap();
return new ModelAndView(des, map);
}
public ModelAndView process(HttpServletRequest request, HttpServletResponse response) ...{
String des = "dispatchView/result";
logger.debug("demoDao= " + demoDao);
UserModel model = demoDao.getDateById("01000001");
return new ModelAndView(des, "model", model);
}
}
private DemoDao demoDao;
public void setDemoDao(DemoDao demoDao) ...{
this.demoDao = demoDao;
}
public ModelAndView index(HttpServletRequest request, HttpServletResponse response) ...{
String des = "";
Map map = new HashMap();
return new ModelAndView(des, map);
}
public ModelAndView process(HttpServletRequest request, HttpServletResponse response) ...{
String des = "dispatchView/result";
logger.debug("demoDao= " + demoDao);
UserModel model = demoDao.getDateById("01000001");
return new ModelAndView(des, "model", model);
}
}
Spring Framework这个曾经令我钦佩的框架结构第一次让我在小河沟里翻了船,配置的这么好,怎么可能注入不了呢?令我足足郁闷了一天......
都说一个人在极度失望的时候就会看到事情的转机,因为我确实是在开始怀疑是不是我乘公汽没有主动给老大爷让座或者是那天在地上拣到五分钱没有交公而造成的这个莫名其妙的错误的时候,转机出现了。冥冥中我好像看到了相同一个class我定义了两遍,天哪,难道真是这个原因???于是我把spring-context.xml中明为dispatchCtrl的bean定义删掉了,把demoDaoImpl的注入写在了dispatch-servlet.xml的dispatchController bean中,为了方便,我把demoDaoImpl也写在了demoDaoImpl中,再运行,就好了。
这个问题值得好好总结一下,难道是Spring在启动加载类的时候相同的类就不再第二次注入了?暂时不得而解,先记录再此,看看有没有大侠给我个合理的解释。