一、准备后续执行过程用到的一些属性
1)先从ClassPathXmlApplicationContext类入口,以下面的类路径一直调用父类的构造方法以达到给后续 要用的属性赋值: 下面是在调用构造方法时,类加载的过程是从下往上- ClassPathXmlApplicationContext:- 这个类就一个属性- private Resource[] configResources; 资源路径- AbstractXmlApplicationContext:- 这个类就一个属性- private boolean validating = true; 设置xml文件的验证标志,默认是true- AbstractRefreshableConfigApplicationContext:- 这个类就涉及到两个属性- private String[] configLocations; 配置文件路径- private boolean setIdCalled = false; 不太清楚,后续再回来改- AbstractRefreshableApplicationContext:- 这个类主要涉及到四个属性- private Boolean allowBeanDefinitionOverriding; 是否请允许覆盖bean定义信息- private Boolean allowCircularReferences; 是否允许循环依赖- private DefaultListableBeanFactory beanFactory; 大名鼎鼎bean工厂- private final Object beanFactoryMonitor = new Object(); 对象锁- AbstractApplicationContext:- 这个类中涉及到的属性比较多,代表性的有- private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>(); bean工厂后置处理器容器- private ConfigurableEnvironment environment; 上下文环境- private ResourcePatternResolver resourcePatternResolver; 创建一个资源模式解 析器PathMatchingResourcePatternResolver(其实就是用来解析xml配置文 件)2)设置AbstractRefreshableConfigApplicationContext类中的属性configLocations(外面传进来的配 置文件路径)3)上面做完后,接着还要做一些准备工作,其中最重要的一点就是initPropertySources();这个方法在 spring源码里面是空的,留给我们扩展用的,我们可以继承ClassPathXmlApplicationContext类来重 定这个方法, 我们可以在重写的方法里面做的事情:在上下文环境中初始化任何占位符属性来源。当然还有些其他准备如:事件容器、应用程序监听器容器等准备工作
二、创建bean工厂并加载xml配置文件生成BeanDefinition对象添加进bean工厂
1)主要分下面四大步执行// 创建DefaultListableBeanFactory对象- DefaultListableBeanFactory beanFactory = createBeanFactory();// 为了序列化指定id,可以从id反序列化BeanFactory对象- beanFactory.setSerializationId(getId());// 定制BeanFactory,设置相关属性,包括是否允许覆盖同名称的对象以及循环依赖,// 和上面一样,我们也可以来重写这个方法- customizeBeanFactory(beanFactory);// 初始化documentReader,并进行xml文件读取及解析,这步是灵魂,后续要多次翻看// 这里面还可以实现自定义标签:- loadBeanDefinitions(beanFactory);实现要有下面几样东西1、命令空间处理类:- 继承NamespaceHandlerSupport类重写init()方法,可参考ContextNamespaceHandler这 个类2、标签解析类,- 继承AbstractSingleBeanDefinitionParser类重写getBeanClass和doParse这两个方 法,可参考PropertyPlaceholderDefinitionParser类3、在resources目录下建个META-INF目录,建下面这两个文件- spring.handlers:配置例如: http\://www.xiong.com/schema/user=com.xiong.selftag.UserNamespaceHandler- spring.schemas:配置例如:http\://www.xiong.com/schema/user/fan.xsd=META-INF/fan.xsd4、 在创建个fan.sxd文件
三、bean工厂的一些准备工作
// 设置beanFactory的表达式语言处理器beanFactory.setBeanClassLoader(getClassLoader());// 设置beanFactory的表达式语言处理器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性值编辑设置管理的一个工具类beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 添加beanPostProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 设置要忽略自动装配的接口,这些接口的实现是由容器通过set方法进行注入的// 所以在使用autowire进行注入的时候需要将这些接口进行忽略beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));下面来说上面第6行如何实现像它一样扩展一个自定义的属性值编辑器:核心:首先spring中给我们提供了一个CustomEditorConfigurer配置类,这个配置类是实现了BeanFactoryPostProcessor接口,意味着实现类就是一个后置处理器了,也就是说,spring在执行过程会调用refresh方法中的invokeBeanFactoryPostProcessors方法,而这个方法中会对所有实现了BeanFactoryPostProcessor接口的类提前创建出一个bean实例出来,然后依次调用每个实例的postProcessBeanFactory方法来执行我们自己要扩展的一些逻辑处理其次:CustomEditorConfigurer这个配置类中最重要的两个属性propertyEditorRegistrars、customEditors:propertyEditorRegistrars:可以用来存储属性值编辑器注册类,这个注册类首先要实现PropertyEditorRegistrar接口,进而实现方法registerCustomEditors,在这个方法中可以把实现接口PropertyEditor(里面有个setAsText方法)的一个类的实例对象添加到后面需要用的一个map中去customEditors:这个属性就直接存储属性值编辑器了,这个可以直接在CustomEditorConfigurer类bean创建时会给这个属性赋值一个编辑器了,后续会把这个里面编辑器添加到一个map中去以供后面使用
bean工厂后置处理器的执行操作
会执行这个方法invokeBeanFactoryPostProcessors(beanFactory);这个方法里面的代码不算复杂:大致记住两个接口就能理解了:1、BeanDefinitionRegistryPostProcessor: 这个接口是下面接口的子接口:其主要作用是beanDefinition进行增删改, 同时也可以实现下面接口的功能2、BeanFactoryPostProcessor:这个接口主要作用是对bean工厂的一些属性进行增删改
ConfigurationClassPostProcessor类分析
这个类主要作用是完成注解形式的生成bean定义信息
注册BeanPostProcessor类型的所有bean后置处理器

