Spring 源码篇-Spring Bean

spring Bean

启动

使用BeanFactory启动Spring,使用xmlBeanFactory读取xml配置。
* BeanFactory:获取bean,判断bean是否存在,获取别名,scope确定等接口;
* ListableBeanFactory:可以根据类型、注解批量获取bean,获取bean定义相关数据;
* HierarchicalBeanFactory:分层bean,获取父beanFactory;
* SimpleJndiBeanFactory:通过jndi配置获取;
* AutowireCapableBeanFactory:实现自动装配的功能,提供了创建bean,销毁bean等操作;
 @Test
    public void test2(){
        BeanFactory beanFactory=new XmlBeanFactory(new ClassPathResource("application.xml"));
        HelloService helloService=beanFactory.getBean("helloService", HelloService.class);
        System.out.println(helloService.hello("mixi"));
    }

Spring 源码篇-Spring Bean_第1张图片

使用ApplicationContext启动Spring 。

采用配置文件形式(classPathxml)。ApplicationContext继承 EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver接口,不仅实现了bean获取、分层bean的接口,还扩展了spring环境(配置参数、profile)、国际化支持(MessageSource),事件触发(bean创建事件、刷新事件等)、获取资源(资源可能为classPath,或者systemPath等等)。

 @Test
    public void test(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:application.xml");
        System.out.println(applicationContext.getApplicationName());
        HelloService helloService=applicationContext.getBean("helloService", HelloService.class);
        System.out.println(helloService.hello("mixi"));
    }

配置文件如下:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="helloService" class="com.mixi.spring.demo.ioc.service.impl.HelloServiceImpl">bean>
beans>

ClassPathXmlApplicationContext是从classpath xml配置文件下获取,其他的包括FileSystemXmlApplicationContext(从文件系统获取xml配置),XmlServletWebServerApplicationContext(从web应用的根目录读取配置文件,需要先在web.xml中配置),AnnotationConfigServletWebServerApplicationContext(通过注解方式获取配置),ReactiveWebServerApplicationContext(响应式的web配置),AnnotationConfigReactiveWebServerApplicationContext(通过配置响应式配置),AnnotationConfigWebApplicationContext(注解形式),GroovyWebApplicationContext(groovy配置)
Spring 源码篇-Spring Bean_第2张图片

  • ClassPathXmlApplicationContext 源码查看
public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		//设置父级applicationContext
		super(parent);
		//设置配置目录
		setConfigLocations(configLocations);
		if (refresh) {
			//重点在刷新着,此方法可以手动调用,自己刷新
			refresh();
		}
	}
	public void refresh() throws BeansException, IllegalStateException {
	//同步块
		synchronized (this.startupShutdownMonitor) {
			//准备刷新,记录启动时间,配置文件重新初始化,applicationListener重新初始化
			prepareRefresh();

			// beanFactory刷新及获取,BeanDefinition 初始化,但未初始化bean
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
			prepareBeanFactory(beanFactory);

			try {
				// 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
         // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
 
         // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化,可修改配置BeanDefinition 
         // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
				postProcessBeanFactory(beanFactory);

				// 执行postProcess beanFactory
				invokeBeanFactoryPostProcessors(beanFactory);

				//注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
				registerBeanPostProcessors(beanFactory);

				//初始化国际化
				initMessageSource();

				//初始化事件广播器
				initApplicationEventMulticaster();

				 // 从方法名就可以知道,典型的模板方法(钩子方法),
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
				onRefresh();

				// 注册事件监听器,监听器需要实现 ApplicationListener 接口
				registerListeners();

				// 初始化所有的 singleton beans
         		//(lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				// 最后,广播事件,ApplicationContext 初始化完成
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				//异常结束,需要销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
				destroyBeans();

				//刷新失败
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// 清缓存
				resetCommonCaches();
			}
		}
	}

创建beanFactory过程中,将初始化bean定义。源码如下

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {//是否已经初始化了beanFactory,已经初始化了需要销毁bean,同时关闭BeanFactory
			destroyBeans();
			closeBeanFactory();
		}
		try {	
			//创建BeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//设置序列化ID
			beanFactory.setSerializationId(getId());
			//自定义Factory,配置是否能够bean覆盖和循环应用
			customizeBeanFactory(beanFactory);
			//加载bean定义
			loadBeanDefinitions(beanFactory);
			//互斥设置
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

加载bean定义过程,即loadBeanDefinitions(),先查看BeanDefinition,此类定义了bean加载的信息。

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
 
   // 我们可以看到,默认只提供 sington 和 prototype 两种,
   // 很多读者都知道还有 request, session, globalSession, application, websocket 这几种,
   // 不过,它们属于基于 web 的扩展。
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
 
   // 比较不重要,直接跳过吧
   int ROLE_APPLICATION = 0;
   int ROLE_SUPPORT = 1;
   int ROLE_INFRASTRUCTURE = 2;
 
   // 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。请参见附录介绍
   void setParentName(String parentName);
 
   // 获取父 Bean
   String getParentName();
 
   // 设置 Bean 的类名称
   void setBeanClassName(String beanClassName);
 
   // 获取 Bean 的类名称
   String getBeanClassName();
 
 
   // 设置 bean 的 scope
   void setScope(String scope);
 
   String getScope();
 
   // 设置是否懒加载
   void setLazyInit(boolean lazyInit);
 
   boolean isLazyInit();
 
   // 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
   // 是 depends-on="" 属性设置的值。
   void setDependsOn(String... dependsOn);
 
   // 返回该 Bean 的所有依赖
   String[] getDependsOn();
 
   // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
   // 如果根据名称注入,即使这边设置了 false,也是可以的
   void setAutowireCandidate(boolean autowireCandidate);
 
   // 该 Bean 是否可以注入到其他 Bean 中
   boolean isAutowireCandidate();
 
   // 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
   void setPrimary(boolean primary);
 
   // 是否是 primary 的
   boolean isPrimary();
 
   // 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
   void setFactoryBeanName(String factoryBeanName);
   // 获取工厂名称
   String getFactoryBeanName();
   // 指定工厂类中的 工厂方法名称
   void setFactoryMethodName(String factoryMethodName);
   // 获取工厂类中的 工厂方法名称
   String getFactoryMethodName();
 
   // 构造器参数
   ConstructorArgumentValues getConstructorArgumentValues();
 
   // Bean 中的属性值,后面给 bean 注入属性值的时候会说到
   MutablePropertyValues getPropertyValues();
 
   // 是否 singleton
   boolean isSingleton();
 
   // 是否 prototype
   boolean isPrototype();
 
   // 如果这个 Bean 原生是抽象类,那么不能实例化
   boolean isAbstract();
 
   int getRole();
   String getDescription();
   String getResourceDescription();
   BeanDefinition getOriginatingBeanDefinition();
}

你可能感兴趣的:(Spring)