1. 程式人生 > >Spring依賴注入,帶來的資料初始化問題

Spring依賴注入,帶來的資料初始化問題

applicationContext.xml配置檔案1.舉個例子:<bean id="AService" class="com.backgroud.restful.AService"> </bean><context:component-scan base-package="com.front.restful" /><bean id="BService" class="com.backgroud.restful.BService"> </bean>初始化順序:1.先初始化AService2.再初始化com.front.restful包下的service類3.最後才初始化BServicexml裡面配置的bean,和註解掃描的包中的bean,初始化的順序,是交叉依次執行的拓展應用:假如存在一個系統資料字典變數 jdbcUrl,預設是null值,它的初始化動作,交由com.front.restful包下的Rservice類進行初始化,而後續BService引用該資料字典變數 jdbcUrl 時,則能獲取到非空值,從而進行業務操作。(靜態變數,之所以用bean初始化,是因為有的就是需要讀資料庫,然後進行值初始化,而不是一個簡單的常量,直接在程式碼裡面寫死,這個地方需要注意一下,在這也不進行這種初始化方式的評判,更多的是說明問題。。)2.引入的bug:有些service初始化時,不一定是按xml配置的bean依次執行,舉個例子:<bean id="AService" class="com.backgroud.restful.AService"> <property name="BService" ref="BService" /> </bean><context:component-scan base-package="com.front.restful" /><bean id="BService" class="com.backgroud.restful.BService"> </bean>初始化順序1.先初始化AService2.依賴注入原因,直接初始化BService3.再初始化com.front.restful包下的service類比較:
xml裡面配置的bean,和註解掃描的包中的bean,初始化的順序,已經不是按照xml配置的順序執行了,這個時候就有可能引入bug。拓展應用中的bug:存在一個系統資料字典變數 jdbcUrl,預設是null值,它的初始化動作,沒有先交由com.front.restful包下的Rservice類進行初始化,而是直接被後續BService,引用了該資料字典變數 jdbcUrl ,從而獲取到了空值,最終影響了業務的正常邏輯操作。結論:1.這是一個比較難以發現的bug問題,如果現實開發中,如果一開始AService,沒有依賴BService,則不會有jdbcUrl,初始化為空值的現象。2.但是隨著業務的增長,有可能AService需要對BService進行引用,這個時候就會突然出現jdbcUrl初始化為空值的問題,這個時候,在這個問題解決的程序中,開發人員花銷的時間也因人而異,但無疑是痛苦的。3.這是一種比較淺的引用關係,設想一下,如果xml配置如下:<bean id="AService" class="com.backgroud.restful.AService"> <property name="CService" ref="CService" /> </bean><context:component-scan base-package="com.front.restful" /><bean id="BService" class="com.backgroud.restful.BService"> </bean><bean id="CService" class="com.backgroud.restful.CService"> <property name="BService" ref="BService" /> </bean>那麼由於業務的增長,AService需要對CService進行引用,從而造成了BService的提前初始化,進而影響了jdbcUrl的值初始化,這種問題的解決難度,無疑又往上增加。而且隨著xml的各種依賴注入層級增加,到最後,可能會發現不了問題程式碼,或者找到了問題程式碼,因為沒有洞悉引用邏輯,也成為了一道無法解決的題,最終只能進行程式碼回退來解決。解決:
這種問題,在現實開發中,是有可能能遇到的,如果把靜態變數的初始化工作bean,直接放在xml定義的最前面,基本便能解決了。但是因為很多時候,我們沒有注意到這個問題,便會帶來不必要的麻煩。如:<context:component-scan base-package="com.front.restful" /><bean id="AService" class="com.backgroud.restful.AService"> <property name="CService" ref="CService" /> </bean><bean id="BService" class="com.backgroud.restful.BService"> </bean><bean id="CService" class="com.backgroud.restful.CService"> <property name="BService" ref="BService" /> </bean>最後,有則改之,無則加勉。

相關推薦

Spring依賴注入帶來資料初始問題

applicationContext.xml配置檔案1.舉個例子:<bean id="AService" class="com.backgroud.restful.AService"> </bean><context:component-scan

Spring依賴注入AOP

依賴注入 構造引數注入        --> 常用的是方案一和方案二         MyBean類  YouBean類 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www

spring依賴注入執行報空指標異常

java.lang.reflect.InvocationTargetException     sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     sun.reflect.NativeMethod

Spring整理系列(02)——spring依賴注入組裝物件之間的依賴關係

上篇文章整理了spring容器註冊bean的實現方式,本文將整理spring注入bean的實現方式,多數文章按照setter和構造器注入的緯度來介紹,本文將按照如何採用setter和構造器的緯度來整理,即xml配置注入、xml配置自動裝配、註解自動裝配三種方式,

Spring依賴注入(構造引數注入、集合陣列屬性注入、XML自動注入 全註解配置)

依賴注入 構造引數注入        --> 常用的是方案一和方案二         MyBean類  YouBean類 <?xml version="1.0" encodin

SpringBoot使用@RunWith(Parameterized.class)進行引數測試同時支援依賴注入以及CommandLineRunner在單元測試時不執行主程序

問題提出 在使用SpringBoot進行單元測試的時候,我發現了兩個問題 使用引數化測試的時候,必須使用 @RunWith(Parameterized.class),而對Spring進行單元測試時,如果想使用依賴注入,即使用 @Autowired 註解,需要使

laravel 資料模型和依賴注入輕鬆刪除1對多記錄

laravel是PHP框架,以下操作似乎沒有用到PHP和MYSQL語句,就這麼優雅地搞定了: 有兩個表: 賽事表:races 賽事專案表:items (包含欄位:race_id) 一個賽事有多個比賽專案,多個比賽專案對應一個賽事。 建立模型: Race.php <?php

spring依賴注入(二)-java注入xml注入混合注入

java注入 @Configuration public class CDPlayerConfig { @Bean public CompactDisc compactDisc(){

Linux系統--CentOS7下Mysql(docker)映象建立使用者表以及資料初始

1.docker下載(環境為centos7)yum install docker-engine2.下載完成後啟動docker使用命令:service docker start3.為docker下載映象提速curl -sSL https://get.daocloud.io/da

Spring】Springboot監聽器啟動之後初始工作

package com.laplace.laplace.common.starter.config; import java.io.IOException; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springfram

spring3.1整合quartz時spring依賴注入無法注入到quartz的job中的處理方法

定時任務類 package cn.customercard.controller; import java.util.Date; import javax.servlet.ServletContextEvent; import javax.serv

Spring依賴注入方式為什麼Spring4.0提倡使用建構函式注入方式?

先回答題目中的問題: 基於建構函式或基於setter的DI? 何時使用構造注入,何時使用setter注入,經驗法則是:強制依賴用構造,可選依賴用Setter。注意,在settter方法上使用@Required註解即可令屬性強制依賴。  Spring 團隊建議,構造注入的例項是不

[轉]Spring依賴注入和例項(new)的差別

Spring依賴注入和例項化(new)的差別。 Sping為什麼使用依賴注入而不使用例項化物件的方式? 首先說明一下概念 依賴注入(Dependency of Injection)和控制反轉(Inversion of Control 簡稱

Spring類註冊不上applicationContext不初始在Filter中無法getBean、使用Dao、Service等

新建一個xml檔案,裡面複製下面內容: <?xml version="1.0" encoding="UTF-8"?>   <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springf

關於spring boot 的啟動載入 一些初始資料

方法一: 如何載入一些啟動就需要的初始化資料呢? 為了解決這樣的問題,spring Boot 為我們提供了一個方法,通過實現介面 CommandLineRunner 來實現。無需其他配置,只要建立

Spring 依賴注入三種方式的實現及迴圈依賴問題的解決(原始碼+XML配置)

搬磚啦,搬磚啦,這幾天在看Spring相關的書,下面給大家分享一下這幾天的心得與收穫,Go Go Go! Spring支援兩種依賴注入方式,分別是屬性注入,建構函式注入。除此之外,Spring還支援工廠注入方式。 接下來,我們一起來了解一下Spring的幾種注入方式。

Spring依賴注入,自動掃描元件自動裝配註解注入

Spring 依賴注入 Spring框架中,依賴注入(DI)的設計模式是用來定義物件彼此間的依賴。它主要有兩種型別: Setter方法注入 構造器注入 <!-- 建立一個 Spring bean 的配置檔案,並在這裡宣告所有的Java物件的依賴。 --

tomcat啟動但是spring配置的bean並沒有初始

今天在做一個spring配置定時器的任務時,發現定時器並沒有啟動。 但是所有的定時器spring的配置程式碼是毫無錯誤的:  <bean id="timerBeanId" class="timerBean">               </bean&g

SpringBoot 原始碼解析 (三)----- Spring Boot 精髓:啟動時初始資料

在我們用 springboot 搭建專案的時候,有時候會碰到在專案啟動時初始化一些操作的需求 ,針對這種需求 spring boot為我們提供了以下幾種方案供我們選擇: ApplicationRunner 與 CommandLineRu

c++全局變量局部變量內存布局默認初始

def 布局 內存布局 con glob efi 靜態存儲區 cal 自定義類 全局變量 定義在所有函數之外的變量,main函數之內的變量也是局部變量,Globle variable 未顯示初始化時執行默認初始化 局部變量 定義在函數之內的變量,Local variabl