1. 程式人生 > >Spring (IOC)筆記

Spring (IOC)筆記

單例和多例

  • 註解中宣告單例通過@Scope,配置檔案就是在bean的xml中加scope屬性
  • spring預設類是單例的,而且在IOC容器啟動時就建立了例項
  • 如果使用多例,物件在使用時建立
  • 單例bean可以通過懶載入實現單例bean在使用時建立
  • SpringMVC中的controller預設是單例的,在web中,不能在controller中新增非靜態成員變數,如果非要使用,就將controller宣告為多例的.這是因為單例的controller在web的併發情況下是不安全的,非靜態成員變數會被重複利用而無法滿足需求.

給容器中註冊元件

  • 包掃描@componentScan
    +元件標註註解 (@Controller/@Service/@Repository/@Component)[我們自己的bean]
  • @Bean[匯入的第三方包裡面的元件]
  • @Import[快速給容器中匯入一個元件]
    1:@Import(). 引數為類的型別 .class
    2:引數還可以為一個ImportSelector介面的實現類,該實現類返回需要匯入的類的全限定名組成的字串陣列.spring-boot底層用的很多
    3:引數還可以是一個ImportBeanDefinitionRegistrar介面的實現類,
  • 使用FactoryBean建立bean
    使用時建立一個實現FactoryBean的實現類,內部實現工廠bean的三個抽象方法,
    工廠bean的作用是包裝一個bean,在getObject()方法的實現中實現自己想實現的功能,返回的是被包裝的bean.在其他地方獲取這個工廠bean,得到的bean型別是被包裝的bean,如果想獲取工廠bean,在名稱前加上"&"即可.

Bean的初始化和銷燬(Bean的生命週期)

  • 我們可以自定義初始化和銷燬方法
  • (單例)容器啟動時呼叫bean的構造器,bean建立並賦值好後呼叫初始化方法,容器關閉時,呼叫bean的銷燬方法
  • (多例)獲取bean的時候建立bean,bean建立好並賦值好後呼叫初始化方法,容器關閉不呼叫銷燬方法,容器不會管理多例項bean.
  • 指定初始化和銷燬方法 :
    1:在bean類中建立初始化和銷燬方法,然後在@Bean()中通過init-method和destroy-method方法指定自己自定義的初始化和銷燬方法.
    2:通過讓bean實現InitializingBean介面實現初始化 , 通過讓bean實現DisposableBean介面實現銷燬
    3: 使用JSR250的@PostConstruct
    ,執行初始化 @PreDestroy執行銷燬
    4:通過實現BeanPostProcessor介面指定初始化前後的操作
  • spring 底層對BeanPostProcessor的使用
    bean賦值,注入其他元件,@Autowired,生命週期註解功能,@Async

屬性賦值

  • @Value
    1 : 使用基本數值賦值
    2 : 使用SpEL: #{}
    3: 可以寫${} :去除配置檔案(.properties)中的值(執行在環境變數中的值)
    4 : 在配置類上加 @PropertiesSource()/@PropertiesSources()載入外部配置檔案,儲存在執行的環境變數中

自動裝配

  • @Autowired
    • 預設優先按照型別去容器中尋找相對應的元件,applicationContext.getBean(.class)
    • 如果找到多個相同型別的元件,再將屬性的名稱作為id去尋找bean
    • 如果需要指定bean名稱,使用@Qualifier(name)
    • 自動裝配預設一定要將屬性賦值好,否則會報錯
    • 通過autowired的required = false選擇非必須裝配
    • 使用@Primary是標註在bean宣告上的,使得spring遇到相同型別bean選擇時,首選這個bean
    • 可以在構造器,setter,引數,屬性處使用
    • @Autowired標註在setter方法上,spring呼叫方法建立bean,如果該bean的建立需要另一個bean,將需要的bean作為setter方法的引數,spring在構造時,會從容器中拿到bean注入
    • 構造器上,預設載入容器中的元件,容器啟動時會自動呼叫無參構造器建立物件,將@Autowired加在有參構造器上,spring建立時呼叫有參構造器,如果bean只有一個有參構造器,有參構造器的@Autowired可以省略
    • @Bean標註的方法建立物件時,方法引數如果是另一個bean,從容器中獲取,這個方法引數可以使用或不使用@Autowired
  • @Resource@Inject [Java 規範] 脫離spring也可以用
    • @Resource(name=)預設按照元件名稱進行裝配,不支援@Promary和required
    • @Inject沒有required
  • 自定義元件(bean)想要使用Spring底層的元件(ApplicationContext/BeanFactory),需要實現XXXAware介面:在建立物件的時候,會呼叫介面規定的方法注入相關元件
    • ApplicationContextAware介面,實現setApplicationContext方法,將applicationContext獲取到bean中
  • @Profile
    • 指定元件(bean)在哪種環境中才能被建立,預設是default環境
    • spring為我們提供的根據當前環境,動態的切換和啟用一系列的功能
    • 例如,我們需要實現不同開發階段的資料來源的切換,我們首先建立不同資料來源的bean,然後在不同bean上標註@Profile(環境名),
    • 切換環境:
      • 在執行引數中新增 -Dspring-profiles.active = 環境名
      • 使用AnnotationConfigApplicationContext無參構造器建立ApplicationContext物件applicationContext,然後使用applicationContext.getEnvironment().setActiveProfiles(環境名)設定環境,再使用applicationcontext.register(主類.class)註冊主配置類,最後啟動重新整理容器applicationContext.refresh()
    • @Profile也可以寫在配置類上,只有在指定環境下才載入配置類

IOC