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方法是不會起作用的,報各種錯誤