欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Bean的初始化

程序员文章站 2022-05-21 22:13:51
...

基于注解驱动

AnnotationConfigApplicationContext 为Spring Context、上下文、容器。

 public static void main( String[] args )
    {
    	AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
    	
    	System.out.println(ac.getBean("example"));	
    }

Spring Bean工厂在代码的实现类为DefaultListableBeanFactory。该类实现了BeanFactory接口。

AnnotationConfigApplicationContext

构造方法

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		//注册Bean  类似于ac.register(App.class);
		register(annotatedClasses);
		//启动容器
		refresh();
	}

refresh()

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			
           /*
			*  扫描类并将符合Spring规则的类解析成一个BeanDefinition对象
	        *
		    */		
			prepareRefresh();
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();


			    /*
			     * 调用该方法实例化对象
			     *
			     */			
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

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

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

DefaultListableBeanFactory

该类中存储了一个beanDefinitionMap,用来存储解析的beanDefinition对象。该Map由CurrentHashMap实现。属于线程安全。

@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

	@Nullable
	private static Class<?> javaxInjectProviderClass;

	static {
		try {
			javaxInjectProviderClass =
					ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - Provider interface simply not supported then.
			javaxInjectProviderClass = null;
		}
	}


	/** Map from serialized id to factory instance */
	private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
			new ConcurrentHashMap<>(8);

	/** Optional id for this factory, for serialization purposes */
	@Nullable
	private String serializationId;
    ...
    

Spring Bean的产生过程

对象与Spring Bean的关系:Spring Bean是一个对象,但对象不一定是Spring Bean

BeanDefinition :Bean的描述对象,描述Spring Bean的一个类。

首先JVM加载类并进行扫描,将符合Spring Bean规则的类解析成GenericBeanDefinition对象。并将对象放入beanDefinitionMap中。

模拟操作【将Class解析成一个BeanDefinition对象 】:

	 
	 	for{
    		
    		//读取类的信息解析成BeanDefinition对象
    		//BeanDefinition对象:描述Bean的对象
	    	GenericBeanDefinition  beanDefinition=new GenericBeanDefinition();
	    	beanDefinition.setBeanClassName(Example.class.getName());
	    	beanDefinition.setBeanClass(Example.class);
	    	beanDefinition.setScope("singleton");
	    	beanDefinition.setLazyInit(false);
	    	...
	    	
	    	//解析完成后,将该对象放入map中进行存储
	    	//map中存储的BeanDefinition对象,即Bean的描述对象
	    	beanDefinitionMap.put("example",beanDefinition);
    	}

干预Spring加载Bean的过程

	@Component
public class MyProcessor  implements  BeanFactoryPostProcessor {

	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		  BeanDefinition beanDefinition = beanFactory.getBeanDefinition("example");
		  beanDefinition.setBeanClassName(Example2.class.getName()); 
	}

}
 	

Spring将Spring Bean解析成一个BeanDefinition描述对象,并存储到Map中,在没有实例化之前,会查看是否有BeanFactoryPostProcessor ,如果有就会执行,用来干预Bean的加载。