Spring通過註解@Autowired注入對象 注意事項

背景描述:項目使用技術比較老,請求直接通過繼承HttpServlet 接收,用spring,jdbcTemplate管理交互數據。

  在servlet層,想要直接注入一個 TenantInfoService

  例如:

TenantInfoService :

@Service
public class TenantInfoService {
   private final static Logger log = LoggerFactory.getLogger(TenantInfoService.class);
   @Autowired
   private TenantInfoDao tenantInfoDao;

   public void updateDeviceIpByUuid(String uuid,String deviceIp){
      log.error("進入TenantInfoService");
      tenantInfoDao.updateDeviceIpByUuid(uuid,deviceIp);
   }

}

TenantInfoDao :

@Repository
public class TenantInfoDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void updateDeviceIpByUuid(String uuid , String ip){
    logger.error("開始執行更新");
    jdbcTemplate.update("update t_device set D_DEV_IP=? where UUID = ?",new Object[]{ip,uuid});
    logger.error("結束執行更新");
}

}

servlet層:

@Autowired
private TenantInfoService tenantInfoService;

  tenantInfoService.updateDeviceIpByUuid(uuid,ip);

問題:在使用是,一直拋出:空指針異常。

原因:由於servlet這個類並沒有被spring容器管理,導致如果想使用註解注入屬性失敗。

 於是,在調試時嘗試使用判斷:

     if(tenantInfoService ==null){

         tenantInfoService  = new TenantInfoService();

     }

    以爲new 一個對象,就可以使用裏面的方法,報空出現在tenantInfoService類中。

   於是在tenantInfoService再加判斷:

    if(tenantInfoDao ==null){

      tenantInfoDao = new TenantInfoDao()

     }

     一直這樣,最後連jdbcTemplate都判斷了,用new JdbcTemplate(),這次不報空,報 NO  DataSource;整個人直接崩潰,心態爆炸。

  最後發現,如果想要用註解的方式在一個類中注入屬性對象,該類也必須先被Spring容器管理。如在該類上加@Compent註解。而我的servlet類沒有被spring管理,後面想要通過判斷方式,自己new 屬性對象。但是,自己new的對象仍然沒有被Spring管理,所以即使自己new的對象中使用了註解注入屬性,也仍然報空。

   解決:可以使用ApplicationContext對象的getBean() 方法獲取被spring管理的類。

 可以參考工具類:

 @Compent//被spring管理

public class BaseHolder implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext;
    
    /**
     * 服務器啓動,Spring容器初始化時,當加載了當前類爲bean組件後,
     * 將會調用下面方法注入ApplicationContext實例
     */
    @Override
    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        System.out.println("初始化了");
        BaseHolder.applicationContext = arg0;
    }
    
    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }
    
    /**
         * 外部調用這個getBean方法就可以手動獲取到bean
     * 用bean組件的name來獲取bean
     * @param beanName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T>T getBean(String beanName){
        return (T) applicationContext.getBean(beanName);
    }
}
 

 


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章