1.spring源码之beanFactory的初始化

spring beanfactory的创建从这行命令开始:

ClassPathXmlApplicationContext ct=new ClassPathXmlApplicationContext("spring-config.xml");

public ClassPathXmlApplicationContext(...)  {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }

 }

关键就是调用了refresh():

@Override
	public void refresh() throws BeansException, IllegalStateException {
		/**
		 * 加锁,说明并发执行,很多地方都有调用
		 * registerShutdownHook 也调用了
		 * close()方法也调有了,
		 * 容器在启动时,不能调Close的方法
		 */
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			/**
			 * 预初始化
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/**
			 *
			 * 创建BeanFactory工厂,告诉子类去刷新内部BeanFactory,
			 * 加载Bean信息,并封装为BeanDefinition,并注册到BeanDefinitionRegistry
			 * key-value key :bean的id value就是BeanDefinition
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * 准备BeanFactory,进行一些设置
			 * Context的类加载器
			 */
			prepareBeanFactory(beanFactory);

			try {
				/**
				 * BeanFactory准备完成后,后置处理器增强,空方法
				 */
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);


				// Invoke factory processors registered as beans in the context.
				/**
				 * 实例化实现了BeanFactoryPostProcessor接口的类中构造方法
				 * 并调用用postProcessBeanFactory 方法
				 *
				 */
				invokeBeanFactoryPostProcessors(beanFactory);


				// Register bean processors that intercept bean creation.
				/**
				 *将实现了BeanPostProcessor的构造方法
				 */
				registerBeanPostProcessors(beanFactory);

				/**
				 * 初始化国际华资源MessageSource组牛
				 */
				// Initialize message source for this context.
				initMessageSource();

				/**
				 * 初始化事件派发器
				 */
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				/**
				 * 空方法
				 * 如果子类重写了这个方法就,调用子类重写的方法tomcat jetty之类的
				 */
				// Initialize other special beans in specific context subclasses.
				onRefresh();

				/**
				 * 注册应用监听器就是实现了ApplicationContextListener接口Bean
				 */
				// Check for listener beans and register them.
				registerListeners();
					/**
					 * 执行构造方法1
					 * setter方法2
					 * 实现了BeanNameAware接口的setBeanName方法3
					 * 实现了BeanFactoryAware接口的 setBeanFactory(BeanFactory beanFactory)方法4
					 * 实现了ApplicationContextAware接口的setsetApplicationContext 方法5
					 * 实现了BeanPostProcessor接口的postProcessBeforeInitialization方法6 ,AOP原理
					 * 标有PostConstruct注解的方法 7
					 * 实现了InitializingBean接口的afterPropertiesSet方法8
					 * 调用配置了init-method方法 9
					 * 实现了BeanPostProcessor接口的postProcessAfterInitialization方法 10
					 *
					 */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				/**
				 * 完成刷新Context,主要调用org.springframework.context.LifecycleProcessor接口onRefresh方法,发布事件ContextRefreshedEvent事件
				 */
				// Last step: publish corresponding event.
				finishRefresh();
			}


这些步骤就是工厂创建的全过程:

1.obtainFreshBeanFactory 创建bean工厂,同时解析xml配置文件,封装成document对象

2.prepareBeanFactory 初始化工厂,赋予属性值

3.postProcessBeanFactory --自定义扩展

4.invokeBeanFactoryPostProcesser–调用factory post process:

可以自定义对bean的元数据做一些修改和扩展

https://blog.csdn.net/baidu_19473529/article/details/81152109

https://blog.csdn.net/mn11201117/article/details/24986325?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache

5.registerBeanPostProcesser --注册bean processer

6.initMessageSource --国际化处理

7.initApplicationEventMulticaster --初始化多播器,方便发布监听事件

8.registerListener --注册监听器(springboot,springmvc中会出现大量…)

9.finishBeanFactoryInitializetion —加载所有非懒加载的单列对象

流程图:

在这里插入图片描述

1.obtainFreshBeanFactory

1.0 主要作用作用

1.初始化 创建beanFactory

2.加载beanDefinition(该类封装了配置文件中bean的信息),并保存在factory中

1.1初始化
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }
   
   
   protected final void refreshBeanFactory() throws BeansException {
        try {
            //createFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            //定制factory ,就是设置了一些属性而已
            this.customizeBeanFactory(beanFactory);
            //加载beanDefinitions
            this.loadBeanDefinitions(beanFactory);
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
    }
1.2 BeanDefinition说明

什么是spring beanDefinition呢?一言概之就是把一个bean实例化出来的模型对象. 有人会问把一个bean实例化出来有Class就行了啊,Class也就是我们通常说的类对象,就是一个普通对象的建模对象,那么为什么spring不能用Class来建立bean呢?很简单,因为Class无法完成bean的抽象,比如bean的作用域,bean的注入模型,bean是否是懒加载等等信息,Class是无法抽象出来的,故而需要一个BeanDefinition类来抽象这些信息,以便于spring能够完美的实例化一个bean

上述文字可以简单理解spring当中的BeanDefinition就是java当中的Class
Class可以用来描述一个类的属性和方法等等其他信息
BeanDefintion可以描述springbean当中的scope、lazy,以及属性和方法等等其他信息

1.3 loadBeanDefinition

该函数的调用链非常麻烦,但目的是很明确的,就是加载配置文件中的bean信息,并封装成beanDfinitions,保存在factory的map结构中

private volatile List<String> beanDefinitionNames = new ArrayList(256);  //存放bean的名称
//存放beanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);


this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

其调用过程的一系列操作如下:

resoucePath(String)->生成 resources(Resource)-> 生成 EncodedResource->获取inputstream,生成InputSource->根据inputSource和resource,生成document对象->生成BeanDefinitionParserDelegate,解析document->调用parseDefaultElement(),对配置文件中的各种信息进行处理:

    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        } else if (delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        } else if (delegate.nodeNameEquals(ele, "bean")) {
            this.processBeanDefinition(ele, delegate);
        } else if (delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }

->processBeanDefinition ()–>registerBeanDefinition()

->最终生成beanDefinition,并放入map集合:

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

2.postProcessBeanFactory

2.0主要作用

spring 留给用户的扩展,该方法在spring中并未被实现

3.invokeBeanFactoryPostProcessors

3.0 主要作用

1.调用用户自定义的postProcessBeanFactory,对bean的元数据进行扩展,

另外,我们有必要对postProcessBeanFactory接口以及BeanPostProcessor进行一个学习和比较

3.1.BeanPostProcessor接口

BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:

public interface BeanPostProcessor {
    //bean初始化方法调用前被调用
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    //bean初始化方法调用后被调用
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

运行顺序

=Spring IOC容器实例化Bean=
=调用BeanPostProcessor的postProcessBeforeInitialization方法=
=调用bean实例的初始化方法=
=调用BeanPostProcessor的postProcessAfterInitialization方法=

在这里插入图片描述

实列

/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
        return bean;
    }

}
3.2postProcessBeanFactory与BeanPostProcessor的区别
简介:

bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。

示例
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
        int count = beanFactory.getBeanDefinitionCount();
        String[] names = beanFactory.getBeanDefinitionNames();
        System.out.println("当前BeanFactory中有"+count+" 个Bean");
        System.out.println(Arrays.asList(names));
    }

}

区别:

注册BeanFactoryPostProcessor的实例,需要重载

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

通过beanFactory可以获取bean的示例或定义等。同时可以修改bean的属性,这是和BeanPostProcessor最大的区别。

4.registerBeanPostProcessors

4.0 主要作用

注册用户自定义的beanPostProcessor,但是并未调用,是等到初始化bean的时候才会调用

5.initApplicationEventMulticaster

5.0 主要作用

1.初始化事件监听多路广播器,方便后续的监听器的注册,也即this.registerListeners();

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            ....
            
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            .......
            }
        }

    }
5.1 观察者模式

这一步骤初始化了applicationEventMulticaster,并在接下去的一个步骤(registerListeners)注册了监听器

实际上是用到了设计模式之观察者模式

如果你还不理解观察模式,请看:

观察者模式

回到该步骤中,当有事件触发时,applicationEventMulticaster会遍历订阅者,触发事件:

并且是将任务提交到线程池中进行的

    public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
        Executor executor = this.getTaskExecutor();
        Iterator var5 = this.getApplicationListeners(event, type).iterator();

        while(var5.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var5.next();
            if (executor != null) {
                executor.execute(() -> {
                    //传播事件
                    this.invokeListener(listener, event);
                });
            } else {
                this.invokeListener(listener, event);
            }
        }

    }

6.finishBeanFactoryInitialization

6.0 主要作用

factory创建完毕,做一些末尾工作,

并开始加载单例bean,因为加载bean又是一个相当复杂的过程,我们放在下一篇文章讲解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值