ssh框架中遇到的问题(2)
Spring注入的时候出现了一个bug,弄了很久,终于找出来了。。
我的这个项目没有使用注解自动注入bean,使用的xml配置自动注入bean,给出相关代码:
AdminDaoImpl.java
public class AdminDaoImpl implements AdminDao {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public List<BuildingType> findAll() {
Query query = sessionFactory.getCurrentSession().createQuery("from BuildingType");
List<BuildingType> buildingtypes = query.list();
System.out.println(buildingtypes);
return buildingtypes;
}
}
AdminServiceImpl.java
public class AdminServiceImpl implements AdminService {
private AdminDao adminDao;
public AdminDao getAdminDao() {
return adminDao;
}
public void setAdminDao(AdminDao adminDao) {
this.adminDao = adminDao;
}
@Override
public List<BuildingType> findAll() {
return adminDao.findAll();
}
}
AdminAction.java
public class AdminAction extends ActionSupport implements ModelDriven<Admin> {
private Admin admin=new Admin();
private AdminService adminService;
@Override
public Admin getModel() {
return admin;
}
public AdminService getAdminService() {
return adminService;
}
public void setAdminService(AdminService adminService) {
this.adminService = adminService;
}
/*
* 管理员登录页面
*/
public String doLogin(){
List<BuildingType> buildingtypes=adminService.findAll();
return "sys_main";
}
}
bean配置:ApplicationBean.xml
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- Admin -->
<bean id="AdminDao" class="com.xxx.dao.AdminDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="AdminService" class="com.xxx.service.AdminServiceImpl">
<property name="adminDao" ref="AdminDao"></property>
</bean>
<bean id="aa" class="com.xxx.action.AdminAction">
<property name="adminService" ref="AdminService"></property>
</bean>
</beans>
为了确保没有写错,ctrl+鼠标左键都能追踪到数据的来源,确认了之后,就启动了项目,结果就报错了。。
exception
java.lang.NullPointerException
com.xxx.action.AdminAction.doLogin(AdminAction.java:50)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
action里面的50行出现了空指针异常,就是这儿List buildingtypes=adminService.findAll();我想不会呀,还是打印一下adminService,结果真是null。。没注入进来?adminService中再打印一下
public void setAdminService(AdminService adminService) {
System.out.println(adminService);
System.out.println(adminService==null);
this.adminService = adminService;
}
结果是一启动就打印了:
[email protected]
false
之后运行
public String doLogin(){
System.out.println(adminService);
List<BuildingType> buildingtypes=adminService.findAll();
return "sys_main";
}
}
打印了null
那是为啥明明注入进来了,也不为null,咋用的时候就成了null呢,我想了一下struts中会为每个方法创建一个实例,那就是后面执行方法的时候没有注入bean 导致对象本身为null(其实这儿我还是没想明白。。),想了很久都没发现问题,都要怀疑人生了,于是我又去看了一下bean的配置文件,看了好像确实没问题啊,这些ref数据源都找的到对应的id呀,幸好事先复制了一份项目,就拿来做比对,好像有点不同。。
原来的都是这样的:
<!-- Admin -->
<bean id="adminDao" class="com.xxx.dao.AdminDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="adminService" class="com.xxx.service.AdminServiceImpl">
<property name="adminDao" ref="adminDao"></property>
</bean>
<bean id="aa" class="com.xxx.action.AdminAction">
<property name="adminService" ref="adminService"></property>
</bean>
</beans>
现在的是这样的:
<!-- Admin -->
<bean id="AdminDao" class="com.xxx.dao.AdminDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="AdminService" class="com.xxx.service.AdminServiceImpl">
<property name="adminDao" ref="AdminDao"></property>
</bean>
<bean id="aa" class="com.xxx.action.AdminAction">
<property name="adminService" ref="AdminService"></property>
</bean>
</beans>
大小写应该不会有问题吧,只要ref和id对应就行了,但还是试了一下,再次打印:
[email protected]
false
[email protected]
[BuildingType [id=1, typename=教学楼, buildings=[Building [id=10, name=10教, describe=5号教学楼, type=1, spaces=[Space [id=14, name=345, describe=dfd教室, size=67, type=10], Space [id=3, name=102, describe=java班教室, size=20, type=10]]], Building [id=9, name=9教, describe=4号教学楼, type=1, spaces=[Space [id=1, name=101, describe=嵌入式教室, size=20, type=9], Space [id=13, name=343, describe=43教室, size=34, type=9]]]]], BuildingType [id=2, typename=实验楼, buildings=[Building [id=3, name=3教, describe=2号实验楼, type=2, spaces=[Space [id=6, name=302, describe=物理实验室2, size=34, type=3], Space [id=5, name=301, describe=物理实验室1, size=34, type=3]]], Building [id=2, name=2教, describe=2号实验楼, type=2, spaces=[Space [id=11, name=601, describe=h5班教室, size=45, type=2], Space [id=2, name=201, describe=化学实验室1, size=30, type=2], Space [id=4, name=202, describe=化学实验室2, size=23, type=2]]]]], BuildingType [id=3, typename=综合楼, buildings=[Building [id=5, name=5教, describe=2号综合楼, type=3, spaces=[Space [id=9, name=501, describe=综合办公室1, size=56, type=5], Space [id=10, name=502, describe=综合办公室2, size=45, type=5]]], Building [id=4, name=4教, describe=1号综合楼, type=3, spaces=[Space [id=8, name=402, describe=综合多媒体教室2, size=34, type=4], Space [id=12, name=602, describe=ui班教室, size=34, type=4], Space [id=7, name=401, describe=综合多媒体教室1, size=45, type=4]]]]]]
竟然是大小写的问题,不得不说自己真是手贱,把id首字母改成大写,遇到了这样的问题,还一直找不到,应该是bean注入的时候,按id注入作为唯一标识(但是为什么启动的时候又能注入进来呢?),就像我们平时写实体类的时候,如果属性的首字母大写的话,应该是set方法是不会起作用的,报各种错误