spring 為什麽可以一統江湖
阿新 • • 發佈:2019-04-30
can 註冊 con 後置處理器 println select fish inf nmon
spring 為什麽可以一統江湖
Inversion of Contro 簡稱IOC 是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。也就是面向接口編程的思想。
簡單的說就是使用配置的方式,修改程序代碼的實現。能靈活的切換代碼,不用修改邏輯代碼。其實就是解決硬編碼創建對象的問題。
學習的路線設定
了解有多少種方式添加對象到容器中
這個很重要,在工作中經常出現類找不到的異常,熟悉這個的話,問題很容易找到。
再從spring對一個類的處理的源碼開始解析spring的原理
Spring配置有兩種,詳細法就可以參考一下Spring的使用教程。
xml配置與註解方式配置。其他本質是一樣的。
- xml
- 配置類上加Configuration
掃描加載bean的規則有,這些不是很重要.
- @bean
<bean id="person" class="com.enjoy.cap1.Person"> <property name="name" value="wolf"></property> <property name="age" value="19"></property> </bean> 或在Configuration類中使用 @Bean("person")
@@Component與@ComponentScan(value = "bgy.bean")
一般用這種,在類上加@Component就可以ComponentScan加載到容器中
@Component
public class Dog{}
- @@Import(bgy.beanout.Fly.class) 單獨加入
@Configuration
@Import(value = { Dog.class })
public class Cap6MainConfig {}
- 實現ImportSelector
public class MyImportSelector implements ImportSelector{ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata){ //返回全類名的bean return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Tiger"}; } } //把MyImportSelector當成bean導入 @Import(value = {ImportSelector.class})
- 使用FactoryBean
public class JamesFactoryBean implements FactoryBean<Monkey>{
@Override
public Monkey getObject() throws Exception {
// TODO Auto-generated method stub
return new Monkey();
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Monkey.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
- 使用JamesImportBeanDefinitionRegistrar
public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/*
*AnnotationMetadata:當前類的註解信息
*BeanDefinitionRegistry:BeanDefinition註冊類
* 把所有需要添加到容器中的bean加入;
* @Scope
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean bean1 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog");
boolean bean2 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat");
//如果Dog和Cat同時存在於我們IOC容器中,那麽創建Pig類, 加入到容器
//對於我們要註冊的bean, 給bean進行封裝,
if(bean1 && bean2){
RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);
registry.registerBeanDefinition("pig", beanDefinition);
}
}
}
小結:
實現的spring包為:spring-context。上下文容器類都是繼承了AbstractApplicationContext 類的。重點:開發時可以按需要自定義上下文。
spring 源碼解析
從加載容器開始
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(myconfig.class);
// ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
上下文抽象類,此設計用的是模板方法設計模式, 在refresh裏 固定好加載時的方法調用順序。
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();//加載 bean的配置定義
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);//如果有配置類則添加配置類處理器,並將優先級排為最高
this.registerBeanPostProcessors(beanFactory);//註冊其他的處理器,並設置好處理順序。
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);//註冊所有註入進來的bean實例到容器中
this.finishRefresh();
} catch (BeansException var9) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
BeanPostProcessors
後置處理器接口,實現了這個接口類可以對所有的類初始化方法進行攔截處理,分別為:postProcessBeforeInitialization,postProcessAfterInitialization
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//返回一個的對象(傳過來的對象)
//在初始化方法調用之前進行後置處理工作,
//什麽時候調用它: init-method=init之前調用
System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
return bean;
}
}
spring 應用組件擴展
待發布
spring 為什麽可以一統江湖