一、配置註解
1. @Configuration 告訴Spring這是一個配置類,此註解等同於配置文件<bean></bean> (類上)
2. @ComponentScan value屬性:指定要掃描的包 (類上)
excludeFilters = Filter[] ,指定掃描的時候按照什麼規則排除哪些組件
FilterType.ANNOTATION 按照註解掃描
FilterType.ASSIGNABLE_TYPE 按照指定類型掃描
3. @Bean 註解在方法上,聲明當前方法的返回值爲一個bean,id默認是方法名。
二、聲明 bean 的註解
@Component 組件,沒有明確的角色
@Service 在業務邏輯層使用(service層)
@Repository 在數據訪問層使用(dao層)
@Controller 在表現層使用,表示爲SpringMVC的控制器
三、@Bean的屬性支持
@Scope 設置Spring容器創建Bean實例的類型(方法上,和@Bean一起使用)
prototype:多實例的,ioc容器啓動並不會去調用方法創建對象放在容器中,每次獲取的時候纔會調用方法創建對象。
singleton:單實例的,ioc容器啓動會調用方法創建對象放到ioc容器中,以後每次獲取就是直接從容器中拿 (map.get())。
request:同一次請求創建一個實例。
session:同一個session創建一個實例。
四、@Import 導入組件
@Import 快速給容器中導入一個組件
1. @Import(要導入的組件) 容器中就會自動註冊這個組件,id默認是全類。
2. ImportSelector:返回需要導入的組件的全類名數組(實現該接口)
3. ImportBeanDefinitionRegistrar :手動註冊bean到容器中(實現該接口)
五、bean 的生命週期
bean的聲明週期分爲:bean創建---初始化---銷燬
1. 容器管理bean的生命週期
我們可以自定義初始化和銷燬方法,容器在bean 進行到當前生命週期的時候來調用我們自定義的初始化和銷燬方法。
調用無參構造(對象創建):
單實例:在容器啓動的時候創建對象
多實例:在每次獲取的時候創建對象
初始化:
對象創建完成,並屬性賦值好,調用初始化方法。。。
銷燬:
單實例:容器關閉時候銷燬
多實例:容器不負責管理這個 bean,容器不會調用銷燬方法。
2. 初始化和銷燬方式
1)指定初始化和銷燬方法
通過@Bean指定init-method和destory-method;
2)通過讓 Bean 實現 InitializingBean(定義初始化邏輯),DisposableBean(定義銷燬邏輯)
3)可以使用JSR250:(使用在方法上)
@PostConstruct:在bean創建完成並且屬性賦值完成,來執行初始化方法
@PreDestroy:在容器銷燬bean之前通知我們進行清理工作
4)BeanPostProcessor 接口 bean的後置處理器,在bean創建之後初始化完成前後進行一些處理工作
postProcessBeforeInitialization:初始化之前進行後置處理工作
postProcessAfterInitialization:初始化之後工作
3. BeanPostProcessor原理 bean的後置處理器
源碼:
首先調用 populateBean(beanName, mbd, instanceWrapper);給bean進行屬性賦值
然後調用 initializeBean 進行初始化 {
創建完bean之後初始化之前:applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
執行自定義初始化:invokeInitMethods(beanName, wrappedBean, mbd);
創建完bean之後初始化之後:applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
Spring底層對 BeanPostProcessor的使用:
bean賦值,注入其他組件,@Autowired,生命週期註解功能,@Async,xxx BeanPostProcessor 等都用到了BeanPostProcessor 。
六、組件賦值
1. @Value 爲屬性注入值
基本數值:@Value("科比")
SpEL表達式:@Value("#{20-2}")
取出配置文件的值:@Value("${person.nickName}") person.nickName爲 properties文件中的屬性。
2. 自動裝配
Spring利用依賴注入(DI),完成對IOC容器中中各個組件的依賴關係賦值。
1)@Autowired:自動注入:
1)、默認優先按照類型去容器中找對應的組件:applicationContext.getBean(BookDao.class);找到就賦值
2)、如果找到多個相同類型的組件,再將屬性的名稱作爲組件的id去容器中查找
3)、@Qualifier("bookDao"):使用@Qualifier指定需要裝配的組件的id,而不是使用屬性名
4)、自動裝配默認一定要將屬性賦值好,沒有就會報錯。
required屬性決定依賴注入是否必選,缺省true,意味着沒有合適類型bean注入時,會拋出異常。
5)、@Primary:讓Spring進行自動裝配的時候,默認使用首選的bean; 也可以繼續使用@Qualifier指定需要裝配的bean的名字。標註了@Primary的 bean 優先注入。
2)Spring還支持使用@Resource(JSR250)和@Inject(JSR330)[java規範的註解]
@Resource:
可以和@Autowired一樣實現自動裝配功能;默認是按照組件名稱進行裝配的。
沒有能支持@Primary功能沒有支持@Autowired(reqiured=false)。
@Inject:
需要導入javax.inject的包,和Autowired的功能一樣。沒有required=false的功能。
AutowiredAnnotationBeanPostProcessor:解析完成自動裝配功能;
3)、 @Autowired:構造器,參數,方法,屬性;都是從容器中獲取參數組件的值
1)、[標註在方法位置]:@Bean+方法參數;參數從容器中獲取;默認不寫@Autowired效果是一樣的;都能自動裝配
2)、[標在構造器上]:如果組件只有一個有參構造器,這個有參構造器的@Autowired可以省略,參數位置的組件還是可以自動從容器中獲取。
3. @PropertySource 讀取外部配置文件
4. @Profile 根據環境,動態激活、切換組件
@Profile:通過設定Environment的ActiveProfiles來設定當前context需要使用的配置環境。(類或方法上)
@Profile:指定組件在哪個環境的情況下才能被註冊到容器中,不指定,任何環境下都能註冊這個組件
1)、加了環境標識的bean,只有這個環境被激活的時候才能註冊到容器中。默認是default環境。
2)、寫在配置類上,只有是指定的環境的時候,整個配置類裏面的所有配置才能開始生效。
3)、沒有標註環境標識的bean,任何環境下都是加載的。