Spring (IOC)筆記
阿新 • • 發佈:2018-12-12
單例和多例
- 註解中宣告單例通過
@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中
- ApplicationContextAware介面,實現
@Profile
- 指定元件(bean)在哪種環境中才能被建立,預設是default環境
- spring為我們提供的根據當前環境,動態的切換和啟用一系列的功能
- 例如,我們需要實現不同開發階段的資料來源的切換,我們首先建立不同資料來源的bean,然後在不同bean上標註
@Profile(環境名)
, - 切換環境:
- 在執行引數中新增
-Dspring-profiles.active = 環境名
- 使用
AnnotationConfigApplicationContext
無參構造器建立ApplicationContext
物件applicationContext
,然後使用applicationContext.getEnvironment().setActiveProfiles(環境名)
設定環境,再使用applicationcontext.register(主類.class)
註冊主配置類,最後啟動重新整理容器applicationContext.refresh()
- 在執行引數中新增
@Profile
也可以寫在配置類上,只有在指定環境下才載入配置類