解決spring懶加載以及@PostConstruct結合的坑
spring懶加載及@PostConstruct的坑
舉例說明:
下面是一個初始化數據的組件
@Component public class InitData { /** * 初始化加載bean */ @PostConstruct public void init() { Map<String, String> map = new HashMap<String, String>(); for (int i=0;i<10;i++) { map.put(i+"", i+""); } //模擬加載一些別單例模式bean的數據初始化 ErrorMsgUtil1.getInstance().setMap(map); ErrorMsgUtil2.getInstance().setMap(map); }
好瞭,如果你開啟瞭spring的懶加載模式,而且 InitData這個bean隻是被掃描而沒有被註入,那麼ErrorMsgUtil裡的map永遠是空的。
@PostConstruct實在bean初始化的時候被創建的,開啟瞭懶加載顯然如果InitData沒有被用到那麼就一直不執行瞭。
此坑已踩,小弟還是對spring理解不深,繼續學習。
ps:如何開啟spring的懶加載模式,在spring.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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd " default-lazy-init="true">
遺留問題 @PostConstruct註入不成功
前兩天做瞭個純java代碼的rabbitMQ監聽多個ip的客戶端功能,由於用的不是配置方式的listener方式—博文中有這一節,無法自動啟動。就用@PostConstruct來項目啟動時運行監聽mq,但是老遇到調用業務邏輯層方法時,註入不成功導致空指針異常。今天排查瞭一下,發現主要問題是框架掃包忽略瞭。
直接先說原因吧
1.忽略ssm本身對註解是通過掃包才讓註解有效的
<!-- 自動掃描該包,支持註解的層限制,把api這個controller層排除在外瞭。另外多個包中間用逗號或者分號隔開都可以。 --> <context:component-scan base-package="com.**.service,com.**.action,com.**.common" > <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.api"/> </context:component-scan>
2.忽略@Service的註解
由於掃包是掃service層和action層(相當於service層),common工具層。所以在api層(相當於controller層)用@Service和不用註解都是錯誤的,都會導致註入失敗。
3.註意掃包區間
出瞭這個范圍@PostConstruct是無效的。應用在啟動時是不會走帶有這個註解的方法的。
4.@PostCoustruct註解用於
在依賴關系註入完成之後需要執行的方法上,以執行任何初始化。此方法所在的類必須放入服務之前調用。也就是該註解的類上不能隨便註解:經驗總結是能用@Service註解,不能用@Controller註解,否則啟動不會走這個方法。這個類定位為服務層/業務層。而不是控制層(web層)
有瞭上面說的註意點。我重新在工具類包common包中寫瞭個測試類。然後spring配置文件上掃包范圍增加瞭這個common包。代碼如下:com.zhanglf.common.cache.CommonCacheMap.java
package com.zhanglf.common.cache; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.zlf.bo.StaffBo; import com.zlf.service.IStaffService; @Service("CommonCacheMap") public class CommonCacheMap { @Resource private IStaffService staffService; @PostConstruct public void getOneStaff(){ StaffBo staffBo = staffService.selectByPrimaryKey("s01"); System.out.println(staffBo.getName()); } }
結果是註入成功,運行結果如下:
這樣@PostConstruct註入問題就解決瞭。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。