- Bean实例的创建:默认是单例
- 为Bean实例设置属性,执行Bean的属性的依赖注入
- 依赖注入:构造方法注入,set方法注入,注解注入(@Autowired)
- 调用Bean实例的初始化方法:initializeBean方法
- 如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
- 如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以)
- 如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
- 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
- 如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
- 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法Spring AOP 会在 IOC 容器创建 bean 实例的最后对 bean 进行处理。其实就是在这一步进行代理增强
- 应用可以通过IoC容器使用Bean
- 容器关闭时,调用Bean的销毁方法
- 在调用初始化方法之前,会调用一系列的aware接口实现,把相关的BeanName,BeanClassLoader以及BeanFactory注入到bean中,然后调用invokeInitMethods之后判断Bean是否有initMethod,如果有,通过invokeCustomInitMethod方法来直接调用,然后完成Bean的初始化。
作用域
- singleton:默认值
- prototype:每次从容器中调用Bean时,都返回一个新的实例,调用getBean时相当于new Bean
- request:每次HTTP请求都会创建一个新的Bean,该作用域仅仅适用于WebApplicationContext环境
- session:同一个Http Session共享一个Bean,不同的Session使用不同的Bean,适用于WebApplicationContext环境
- globalSession:
Spring注解
@controller控制器(注入服务)
@RestController:相当于@ResponseBody+@Controller结合,返回JSON需要在对应的方法上加@ResponseBody
@service 服务(注入dao)
@repository dao(实现dao访问)
@component (把普通的pojo实例化到spring容器中,相当于配置文件中<bean id="" class="">)
@EnableAutoConfiguration:借助AutoConfigurationImportSelector.class(SpringFactoriesLoader.loadFactoryNames())可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器中。
SpringFactoriesLoader:
从META-INF/spring-factories加载配置,有三个静态方法:loadFactories:加载指定的factoryClass并进行实例化。loadFactoryNames:加载指定的factoryClass的名称集合。instantiateFactory:对指定的factoryClass进行实例化。@Autowired和@Resource的区别
1)都可以用来装配bean,都可以写在setter方法上
2)@Autowired默认按类型装配,默认情况下必须要求依赖对象存在,如果要允许null值,设置require属性为false:@Autowired(required=false),想要按照名称装配,接口@Qualifier使用
3)@Resource注解输入J2EE,默认按照名称装配,名称可以通过name属性指定,找不到名称才按照类型装配
IOC容器初始化总结:
-
通过setConfigLocations载入spring配置文件;
-
初始化容器入口通过refresh方法,进入AbstractApplicationContext实现的refresh方法。
-
然后通过obtainFreshBeanFactory方法进入子类AbstractRefreshableApplicationContext实现的refreshBeanFactory刷新一个容器工厂
-
在此创建了DefaultListableBeanFactory类,并调用loadBeanDefinitions(beanFactory)装载bean定义
-
接着以AbstractRefreshableApplicationContext为中心回到此类,进入其子类AbstractXmlApplicationContext实现的loadBeanDefinitions方法。对applicationContext.xml的解析操作,就是解析工厂的那个xml。
-
再接着通过AbstractXmlApplicationContext的loadBeanDefinitions进入到AbstractBeanDefinitionReader类的loadBeanDefinitions。通过获取资源方法resourceLoader.getResource(location),获取到要加载的资源。再真正执行加载功能是其子类XmlBeanDefinitionReader实现的loadBeanDefinitions方法。
-
接着进入XmlBeanDefinitionReader中的loadBeanDefinitions。(XmlBeanDefinitionReader通过调用其父类中调用的DefaultResourceLoader的getResource方法获取要加载的资源)DocumentLoader将Bean定义资源转换成Document对象。
-
doLoadBeanDefinitions中进入DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions 解 析 D ocument对象
-
解析完后,调用DefaultListableBeanFactory类中使用一个HashMap的集合对象存放IoC容器中注册解析的BeanDefinition
参考地址1
[参考地址2](https://javadoop.com/post/spring-ioc
)