清晰圖或者源碼可以加我Q群:940577921 獲取
Spring IOC介紹
IoC也稱為依賴注入(dependency injection, DI)绘盟。它是一個(gè)對(duì)象定義依賴關(guān)系的過程,也就是說(shuō)弄喘,對(duì)象只通過構(gòu)造函數(shù)參數(shù)茅主、工廠方法的參數(shù)或?qū)ο髮?shí)例構(gòu)造或從工廠方法返回后在對(duì)象實(shí)例上設(shè)置的屬性來(lái)定義它們所使用的其他對(duì)象蒙具。然后容器在創(chuàng)建bean時(shí)注入這些依賴項(xiàng)冒萄。這個(gè)過程基本上是bean的逆過程池摧,因此稱為控制反轉(zhuǎn)(IoC)。
在Spring中仓洼,構(gòu)成應(yīng)用程序主干并由Spring IoC容器管理的對(duì)象稱為bean介陶。bean是由Spring IoC容器實(shí)例化、組裝和管理的對(duì)象色建。
IoC容器理念:通過容器將對(duì)象的構(gòu)建方式統(tǒng)一,并且自動(dòng)維護(hù)對(duì)象的依賴關(guān)系舌缤。由 IoC 容器幫對(duì)象找相應(yīng)的依賴對(duì)象并注入箕戳,而不是由對(duì)象主動(dòng)去找。
回顧Bean的使用
bean的配置
// 注冊(cè)一個(gè)bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));
1.xml
<bean id="user" class="com.jiagouedu.bean.User"/>
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
2.實(shí)現(xiàn)FactoryBean
FactoryBean和BeanFactory的區(qū)別国撵,什么情況下返回FactoryBean陵吸,什么情況返回調(diào)用getObject()的結(jié)果
3.@Component ,掃描包
@ComponentScan("com.jiagouedu")
@Configuration
public class AppConfig {
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
4.@Bean
5.@Import
@Import(value = {MyImportBeanDefinitionRegistrar.class,MyImportSelector.class})
?ImportBeanDefinitionRegistrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new RootBeanDefinition(UserServiceImpl.class);
registry.registerBeanDefinition("userServiceImpl",beanDefinition);
}
}
?ImportSelector
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.jiagouedu.bean.Cat"};
}
}
bean的生命周期
bean的生命周期: bean的創(chuàng)建 初始化 銷毀
1.bean的注冊(cè)原理
bean是如何注冊(cè)到容器中的介牙?
BeanDefinition 承載bean的信息壮虫,并注冊(cè)到BeanDefinitionRegistry注冊(cè)器中,bean工廠獲取到注冊(cè)器中對(duì)應(yīng)bean的信息,才能生產(chǎn)bean
BeanDefinition (Bean定義) 承載bean的屬性信息
BeanDefinitionRegistry(Bean注冊(cè)器) bean的id作為key注冊(cè)
AliasRegistry (別名注冊(cè)器) bean的name作為key注冊(cè)
BeanDefinitionReader(Bean定義讀惹羲啤) 讀取配置文件
Beanfactory (bean工廠) 生產(chǎn)bean
示例
//創(chuàng)建一個(gè)簡(jiǎn)單注冊(cè)器
//BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
//實(shí)現(xiàn)注冊(cè)器的工廠
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();
//創(chuàng)建bean定義讀取器
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// 創(chuàng)建資源讀取器
//DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// 獲取資源
//Resource xmlResource = resourceLoader.getResource("spring.xml");
reader.loadBeanDefinitions("spring.xml");
// 裝載Bean的定義
reader.loadBeanDefinitions(xmlResource);
// 打印構(gòu)建的Bean 名稱
System.out.println(Arrays.toString(register.getBeanDefinitionNames());
// 工廠調(diào)用getBean方法
((DefaultListableBeanFactory) registry).getBean("user")
// 注冊(cè)一個(gè)bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));
2.bean的創(chuàng)建流程
Bean創(chuàng)建時(shí)序圖
Debug跟蹤流程:
AbstractApplicationContext#finishBeanFactoryInitialization
ConfigurableListableBeanFactory#preInstantiateSingletons
AbstractBeanFactory#getBean(java.lang.String)
AbstractBeanFactory#doGetBean
markBeanAsCreated(beanName); //標(biāo)記Bean正要?jiǎng)?chuàng)建
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); 是不是抽象的
String[] dependsOn = mbd.getDependsOn(); 有沒有依賴剩拢,先實(shí)例化依賴bean
創(chuàng)建bean實(shí)例
DefaultSingletonBeanRegistry#getSingleton
通過工廠獲取對(duì)象
singletonObject = singletonFactory.getObject();
AbstractAutowireCapableBeanFactory#createBean
Instantiate the bean.
AbstractAutowireCapableBeanFactory#doCreateBean
# 包裝的bean BeanWrapper
instanceWrapper=createBeanInstance(beanName, mbd, args);
AbstractAutowireCapableBeanFactory#createBeanInstance
調(diào)用無(wú)參構(gòu)造器
AbstractAutowireCapableBeanFactory#instantiateBean
#反射
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
//填充bean由 IoC 容器幫對(duì)象找相應(yīng)的依賴對(duì)象并注入,而不是由對(duì)象主動(dòng)去找饶唤。
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);