一、IOC type 1.Xml -- 配置bean 2.Annotation -- @Compoment 3.Class -- @Configuration 4.Properties,YML -- @EnableConfigurationProperties(User.class) @ConfigurationProperties("bnb.user") 二、IOC 注入方式 1.Setter 2.Constructor 3.Factory-method 三、Why IOC 1.模块化 2.可重用性 3.易于扩展 4.可维护 四、Spring IOC API 1.BeanDefinition -- 描述bean的实例,有属性值,构造参数值 2.Resource and ResourceLoader -- 资源和加载资源 3.BeanFactory -- spring bean容器的根接口,定义了容器最基本的功能 4.ApplicationContext -- 为应用程序提供配置的中心接口 五、Spring IOC process resource 核心: XML --> c --> BeanWrapper(实现依赖注入与类型转化) -> Object (获取我们要的对象) 1. BeanDefinition 处理过程 xml or properties ---> ResourceLoader ---> Resource --> XXXReader (XmlBeanDefinitionReader/) --> BeanDefinition (主要是这两种解析值的形式 ConstructorArgumentValues 和 MutablePropertyValues) new ClassPathXmlApplicationContext("") --> org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory --> org.springframework.context.support.AbstractApplicationContext.refreshBeanFactory --> org.springframework.context.support.AbstractRefreshableApplicationContext.loadBeanDefinitions --> org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory) 最终XML解析 是在BeanDefinitionParserDelegate类中完成的 2. BeanWrapper 处理过程 Spring的基础设施的中心接口,继承以下四个接口: ConfigurablePropertyAccessor PropertyAccessor PropertyEditorRegistry TypeConverter 3. 依赖注入过程 Java实例过程: 创建对象 --> 设置属性 --> 初始化方法 IOC实例化过程: CreateBeanInstance --> populateBean --> initializeBean CreateBeanInstance org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean 4.spring 类型转换 类型转换核心类 TypeConverterDelegate 方法 convertIfNecessary ConversionService PropertyEditor 5.spring 容器扩展 BeanPostProcessor :定制化bean逻辑,bean 后置处理器 典型应用场景: 注解式依赖注入 @Autowired @Value AutowiredAnnotationBeanPostProcessor (依赖注入的过程 其实就是根据注解获取注解bean的对象值,然后根据Java反射将bena注入进去) AOP的实现 Spring容器感知 六. 总结 IOC 过程 BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("beanUserTest.xml")); 1. xml -> ResourceLoader -> Resource 2.XmlBeanDefinitionReader.loadBeanDefinitions(resource) -> XmlBeanDefinitionReader.loadBeanDefinitions(new EncodedResource(resource)) 3.XmlBeanDefinitionReader.doLoadBeanDefinitions(InputSource inputSource, Resource resource) 3.1. 将resource转化成document Document doc = XmlBeanDefinitionReader.doLoadDocument(inputSource, resource) -> DocumentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,getValidationModeForResource(resource), isNamespaceAware()); 3.2. reader读取document为注册beanDefinition作准备 XmlBeanDefinitionReader.registerBeanDefinitions(Document doc, Resource resource) -> DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(Document doc, XmlReaderContext readerContext) -> DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root) 3.3. 用自定义或默认解析器解析element DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root) -> DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) -> delegate.parseDefaultElement(ele) / delegate.parseCustomElement(root) 3.4. 用默认解析器解析element过程 DefaultBeanDefinitionDocumentReader.parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) 3.4.1 包含import标签的,则找出引入的resource最后在递归调用loadBeanDefinitions(resource)再次解析 DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(Element ele) -> AbstractBeanDefinitionReader.loadBeanDefinitions(Resource... resources) -> XmlBeanDefinitionReader.loadBeanDefinitions(Resource resource) 3.4.2 包含alias别名的,解析出bean的别名并在aliasRegistered进行注册 DefaultBeanDefinitionDocumentReader.processAliasRegistration(Element ele) -> ReaderContext.fireAliasRegistered(name, alias, extractSource(ele)) -> EmptyReaderEventListener.aliasRegistered(AliasDefinition aliasDefinition) 3.4.3 包含bean标签的,则解析出bean并进行bean的注册到map中 DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) -> BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele) -> BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()) 3.4.4 包含beans标签的 又重新进入3.2步 DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root) 4.获取bean xmlBeanFactory.getBean("test"), AbstractBeanFactory.getBean(name) -> AbstractBeanFactory.doGetBean(name,requiredType) 4.1 转化成真正的bean名,name可能是别名或工厂名等 String beanName = transformedBeanName(name) 4.2 从缓存中获取单利bean,获取到则返回 Object sharedInstance = getSingleton(beanName) 4.3 如果4.2 没有获取到,则获取bean的所有依赖,并将依赖进行注册和创建 String[] dependsOn = mbd.getDependsOn() -> DefaultSingletonBeanRegistry.registerDependentBean(dep, beanName) -> AbstractBeanFactory.getBean(dep); 4.4 如果是单例 mbd.isSingleton(), AbstractAutowireCapableBeanFactory.createBean(beanName, rootBeanDefinition,args) 4.4.1 给BeanPostProcessors处理器一个返回代理而不是目标bean实例的机会。 AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) 4.4.1.1 实例化前置处理器 applyBeanPostProcessorsBeforeInstantiation(targetType, beanName) 4.4.1.2 实例化后置处理器 applyBeanPostProcessorsAfterInitialization(bean, beanName) 4.4.2 创建bean, doCreateBean(beanName, mbdToUse, args) 4.4.2.1 创建bean实例对象 createBeanInstance(beanName, mbd, args) 4.4.2.1.1 有指定的构造函数的创建bean对象 autowireConstructor(beanName, mbd, null, null) 4.4.2.1.2 使用默认构造函数创建bean对象 instantiateBean(beanName, mbd) 4.4.2.2 设置属性,填充值 populateBean(beanName, mbd, instanceWrapper) 给任何实例化的后置处理器修改的机会 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName) 4.4.2.3 初始化bean initializeBean(beanName, exposedObject, mbd) 4.4.2.3.1 更改BeanNameAware/BeanClassLoaderAware/BeanFactoryAware invokeAwareMethods(beanName, bean) 4.4.2.3.2 执行所有getBeanPostProcessors的初始化的前置方法 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 4.4.2.3.3 执行bean的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd) -> ((InitializingBean) bean).afterPropertiesSet() 4.4.2.3.4 执行所有getBeanPostProcessors的初始化的后置方法 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 4.4.3 从bean实例中获取object, bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 4.5 如果是多例 mbd.isPrototype() 则创建一个新的实例对象 4.5.1 将创建中的多例bean存入ThreadLocal<Object> prototypesCurrentlyInCreation =new NamedThreadLocal<Object>中, beforePrototypeCreation(beanName); 4.5.2 将建bean对象 createBean(beanName, mbd, args) 4.5.3 将bean从4.5.1中的prototypesCurrentlyInCreation移除 afterPrototypeCreation(beanName) 4.5.5 从bean实例中获取object, bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 七.介绍 初始化bean的一些方法的执行顺序 1、init-method方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。init-method需要在applicationContext.xml配置文档中bean的定义里头写明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean> 这样,当TestBean在初始化的时候会执行TestBean中定义的init方法。 2、afterPropertiesSet方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。 3、BeanPostProcessor,针对所有Spring上下文中所有的bean,可以在配置文档applicationContext.xml中配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前执行, postProcessAfterInitialization方法在bean初始化之后执行。 总之,afterPropertiesSet 和init-method之间的执行顺序是afterPropertiesSet 先执行,init-method 后执行。从BeanPostProcessor的作用,可以看出最先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。
转载于:https://my.oschina.net/u/3209651/blog/1936666