首頁>技術>

一、容器中注入元件1,包掃描 + 元件標註註解

  原始碼:Demo01_ComponentScan

a)元件標註@Controller@Service@Repository@Componentb)包掃描@ComponentScan

  @ComponentScan中主要值得解釋

value:掃描的包路徑(陣列)excludeFilters:指定掃描的時候按照什麼規則排除那些元件(@ComponentScan.Filter)includeFilters:指定掃描的時候只需要包含哪些元件。使用同excludeFilter。FilterType.ANNOTATION:按照註解FilterType.ASSIGNABLE_TYPE:按照給定的型別FilterType.ASPECTJ:使用ASPECTJ表示式FilterType.REGEX:使用正則指定FilterType.CUSTOM:使用自定義規則useDefaultFilters:是否使用預設的掃描機制。預設按照a)中元件標註掃描2,使用@Bean匯入a)@Scope作用域prototype:多例項的:ioc容器啟動並不會去呼叫方法建立物件放在容器中。每次獲取的時候才會呼叫方法建立物件;singleton:單例項的(預設值):ioc容器啟動會呼叫方法建立物件放到ioc容器中。以後每次獲取就是直接從容器(map.get())中拿,request:同一次請求建立一個例項session:同一個session建立一個例項b)@Lazy

  單例項bean:預設在容器啟動的時候建立物件;

  懶載入:容器啟動不建立物件。第一次使用(獲取)Bean建立物件,並初始化。

c)@Conditional

  @Bean上加改註解,按照一定的條件進行判斷,滿足條件給容器中註冊bean;如在類上加改註解,這個類中配置的所有bean註冊才能生效。

@ConditionalOnClass 表示如果有後面的類,那麼就載入這個自動配置;@ConditionalOnMissingClass 如果沒有後面的類,才自動配置。如果沒有就配置,保證bean的唯一。

  大量運用於SpringBoot中。

3,使用@Import匯入

  原始碼:Demo02_Import

  快速為容器中匯入一個元件。

@Import(要匯入到容器中的元件);容器中就會自動註冊這個元件,id預設是全類名ImportSelector:返回需要匯入的元件的全類名陣列ImportBeanDefinitionRegistrar:手動註冊bean到容器中4,FactoryBean(工廠Bean)

  原始碼:Demo03_FactoryBean

  將實現FactoryBean的類加到容器中。

預設從容器中獲取到的是工廠bean呼叫getObject建立的物件。要獲取工廠Bean本身,我們需要給id前面加一個&二、Bean的生命週期1,bean生命週期

  bean建立 --- 初始化 --- 銷燬

構造(物件建立)單例項:在容器啟動的時候建立物件多例項:在每次獲取的時候建立物件初始化:成員變數賦值,各種增強等,物件建立完成,並賦值好,呼叫初始化方法銷燬:單例項:容器關閉的時候多例項:容器不會管理這個bean;容器不會呼叫銷燬方法;2,定義Bean初始化和銷燬a)定義initMethod和destroyMethod

  原始碼:Demo04_BeanLifeCycle、Car

定義初始化方法,定義@Bean的initMethod為該方法定義銷燬方法,定義@Bean的destroyMethod為該方法b)實現InitializingBean和DisposableBean介面

  原始碼:Demo04_BeanLifeCycle、Dog

定義當前物件實現InitializingBean介面。其中afterPropertiesSet方法會在當前物件設定完屬性之後呼叫。定義當前物件實現DisposableBean介面。其中destroy方法會在當前物件銷燬的時候呼叫。c)可以使用JSR250

  原始碼:Demo04_BeanLifeCycle、Color

@PostConstruct定義在方法上,則該方法會在Bean建立並且屬性賦值之後執行,為初始化方法@PreDestroy定義在方法上,則該方法在容器銷燬bean之前通知我們進行清理工作d)實現BeanPostProcessor,bean的後置處理

  原始碼:Demo04_BeanLifeCycle、Demo04_BeanPostProccessor

  在bean初始化前後進行一些處理工作;

postProcessBeforeInitialization:在初始化之前工作postProcessAfterInitialization:在初始化之後工作3,從原始碼看BeanPostProcessor後置處理器

  在Spring類AbstractAutowireCapableBeanFactory中方法doCreateBean可以看到

//給bean進行屬性賦值populateBean(beanName, mbd, instanceWrapper);//初始化beanexposedObject = initializeBean(beanName, exposedObject, mbd);

  在方法initializeBean中可以看到

//呼叫applyBeanPostProcessorsBeforeInitialization進行初始化之前的處理if (mbd == null || !mbd.isSynthetic()) {    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}//呼叫自定義初始化方法try {    invokeInitMethods(beanName, wrappedBean, mbd);}catch ...//呼叫applyBeanPostProcessorsAfterInitialization進行初始化之後的處理if (mbd == null || !mbd.isSynthetic()) {    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}

總結:

  BeanPostProcessor會在Bean物件建立並屬性賦值完成之後,在執行init初始化方法的前後進行增加。

4,BeanPostProcessor在Spring中的應用a)ApplicationContextAware各種Aware介面

  檢視原始碼類ApplicationContextAwareProcessor實現了BeanPostProcessor介面,其中postProcessBeforeInitialization的實現為:

//如果當前bean為各種指定的Aware的bean就會執行invokeAwareInterfaces方法this.invokeAwareInterfaces(bean);private void invokeAwareInterfaces(Object bean) {    if (bean instanceof Aware) {        ...        //如果當前bean為ApplicationContextAware的子類,則會呼叫其setApplicationContext將applicationContext進行賦值        if (bean instanceof ApplicationContextAware) {            ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);        }    }}

  所以在ApplicationContextAware時,可以透過setApplicationContext獲取到ApplicationContext上下文物件

b)BeanValidationPostProcessor

  檢視BeanValidationPostProcessor實現了BeanPostProcessor介面,其中不管是postProcessBeforeInitialization還是postProcessAfterInitialization,均呼叫了doValidate方法來驗證當前bean是否合理

c)@PostConstruct和@PreDestroy方法

  檢視InitDestroyAnnotationBeanPostProcessor實現了BeanPostProcessor介面,其中postProcessBeforeInitialization在當前bean初始化之前的原始碼為:

//獲取生命週期的metadata,得到標註有@PostConstruct和@PreDestroy的方法LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());try {    //這個方法會採用反射的方式,呼叫方法    metadata.invokeInitMethods(bean, beanName);}...
d)AutowiredAnnotationBeanPostProcessor

  用來處理@Autowire註解的屬性

三、屬性賦值@Value:給屬性賦值,也可以使用SpEL和外部檔案的值@PropertySource:讀取外部配置檔案中的k/v儲存到執行環境中。@PropertySource(value={"classpath:/application.yaml"})@Autowried 裝配優先順序如下:構造器、引數、方法、屬性。使用按照型別去容器中找對應的元件如果找到多個相同型別的元件,再將屬性的名稱作為元件的id去容器中查詢@Qualifier:使用@Qualifier指定需要裝配的元件的id,結合@Autowried使用@Primary:spring自動裝配的時候,預設首先bean,配合@Bean使用@Resource(JSR250):jsr規範:按照元件名稱進行裝配,不支援@Primary和@Autowired(reqiured=false)@Inject(JSR330):jsr規範和@Autowired功能一致,不支援require=false;@Profile:結合@Bean使用,預設為default環境,可以透過命令列引數來切換環境加上VM引數:-Dspring.profiles.active=dev 則採用了dev環境。多個用逗號隔開1.無參構造ApplicationContext,2.透過applicationContext.getEnvironment().setActiveProfiles("dev"),3.註冊配置類applicationContext.register(Main.class),4.採用ApplicationContext.refresh()

7
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • spring與springmvc的整合還放在一個配置檔案嗎