spring接口BeanFactory层级分析

1:spring中的根bean工厂接口为BeanFactory,定义了对bean的基本操作,接口定义如下:

public interface BeanFactory {

	
	Object getBean(String name) throws BeansException;

	
	Object getBean(String name, Class requiredType) throws BeansException;

	
	boolean containsBean(String name) throws BeansException;

	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	
	String[] getAliases(String name) throws NoSuchBeanDefinitionException;

}
 
2:接口HierarchicalBeanFactory继承根接口BeanFactory,用来区分父子容器:
public interface HierarchicalBeanFactory extends BeanFactory {
	
	/**
	 * 返回父容器,没有则返回null
	 */
	BeanFactory getParentBeanFactory();

}

 

 

3: 接口 ListableBeanFactory 同样继承接口BeanFactory,可以用来遍历所有的bean,而不用像BeanFactory中定义的方法必须按照名字一个一个的获取。
public interface ListableBeanFactory extends BeanFactory {

	/**
	 返回本层容器中定义的所有bean,不包含父子层容器中的bean
	 */
	int getBeanDefinitionCount();

	/**
	  不包含父子层容器中的bean
	 */
	String[] getBeanDefinitionNames();
	
	/**
	   不包含父子层容器中的bean 
	 */
	String[] getBeanDefinitionNames(Class type);

	/**
	   不包含父子层容器中的bean 
	 */
	boolean containsBeanDefinition(String name);

	/**
	    不包含父子层容器中的bean 
	 */
	Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans)
	    throws BeansException;

}

 

4:接口AutowireCapableBeanFactory继承自ListableBeanFactory,能够自动注入bean实例并为已经存在的bean实例应用BeanPostProcessors
public interface AutowireCapableBeanFactory extends ListableBeanFactory {

	
	int AUTOWIRE_BY_NAME = 1;

	
	int AUTOWIRE_BY_TYPE = 2;


	
	Object autowire(Class beanClass) throws BeansException;

	
	Object autowireConstructor(Class beanClass) throws BeansException;

	
	void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
			throws BeansException;

	/**
	 * Apply BeanPostProcessors to the given existing bean instance.
	 * Will also check for BeanNameAware and BeanFactoryAware,
	 * which might be implemented as BeanPostProcessors by bean factories.
	 * The returned bean instance may be a wrapper around the original.
	 * @param existingBean the new bean instance
	 * @param name the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one
	 * @throws BeansException if any post-processing failed
	 * @see org.springframework.beans.factory.config.BeanPostProcessor
	 * @see BeanNameAware
	 * @see BeanFactoryAware
	 */
	Object applyBeanPostProcessors(Object existingBean, String name) throws BeansException;

}

 

 

5:接口ApplicationContext继承自 AutowireCapableBeanFactory, HierarchicalBeanFactory,主要能够发布事件,支持国际化,是应用程序主配置类
public interface ApplicationContext extends AutowireCapableBeanFactory, HierarchicalBeanFactory, MessageSource {
	
	
	ApplicationContext getParent();
	
	
	String getDisplayName();

	
	long getStartupDate();

	/**
	 * Notify all listeners registered with this application of an application
	 * event. Events may be framework events (such as RequestHandledEvent)
	 * or application-specific events.
	 * @param event event to publish
	 */
	void publishEvent(ApplicationEvent event);

	/**
	 * <li>Must support fully qualified URLs, e.g. "file:C:/test.dat".
	 * <li>Should support relative file paths, e.g. "WEB-INF/test.dat".
	 * <li>May allow for absolute file paths, e.g. "C:/test.dat".
	 */
	Resource getResource(String location) throws IOException;

 

 

6:应用程序生命周期方法封装在此,避免明显的暴漏给ApplicationContext客户端

 

public interface ConfigurableApplicationContext extends ApplicationContext {

	
	void setParent(ApplicationContext parent);

	
	ConfigurableListableBeanFactory getBeanFactory();

	/**
	 * Load or refresh the persistent representation of the configuration,
	 * which might an XML file, properties file, or relational database schema.
	 * @throws ApplicationContextException if the config cannot be loaded
	 * @throws BeansException if the bean factory could not be initialized
	 */
	void refresh() throws BeansException;

	/**
	 * Close this application context, releasing all resources and locks that the
	 * implementation might hold. This includes disposing all cached singleton beans.
	 * <p>Note: Does <i>not</i> invoke close on a parent context.
	 * @throws ApplicationContextException if there were fatal errors
	 */
	void close() throws ApplicationContextException;

}

 

 

7:

ConfigurableApplicationContext基本实现,有删减,子类实现模板方法

 

public abstract class AbstractApplicationContext implements ConfigurableApplicationContext {

	

	
	private ApplicationContext parent;

	
	private String displayName = getClass().getName() + ";hashCode=" + hashCode();

	
	private long startupTime;

	

	
	private ApplicationEventMulticaster eventMulticaster = new ApplicationEventMulticasterImpl();


	
	public AbstractApplicationContext() {
	}

	
	public AbstractApplicationContext(ApplicationContext parent) {
		this.parent = parent;
	}


	//---------------------------------------------------------------------
	// Implementation of ApplicationContext
	//---------------------------------------------------------------------

	
	public ApplicationContext getParent() {
		return parent;
	}

	
	protected void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	
	public String getDisplayName() {
		return displayName;
	}

	
	public long getStartupDate() {
		return startupTime;
	}

	
	public void publishEvent(ApplicationEvent event) {
		
		this.eventMulticaster.onApplicationEvent(event);
		if (this.parent != null) {
			parent.publishEvent(event);
		}
	}

	
	public Resource getResource(String location) throws IOException {
		if (location.startsWith(ResourceEditor.CLASSPATH_URL_PREFIX)) {
			return new ClassPathResource(location.substring(ResourceEditor.CLASSPATH_URL_PREFIX.length()));
		}
		try {
			// try URL
			URL url = new URL(location);
			return new UrlResource(url);
		}
		catch (MalformedURLException ex) {
			// no URL -> try path
			Resource resource = getResourceByPath(location);
			if (resource == null) {
				throw new FileNotFoundException("Location [" + location + "] could not be opened as path");
			}
			return resource;
		}
	}

	
	protected Resource getResourceByPath(String path) throws IOException {
		return new FileSystemResource(path);
	}

	
	public File getResourceBase() {
		return (new File("")).getAbsoluteFile();
	}


	//---------------------------------------------------------------------
	// Implementation of ConfigurableApplicationContext
	//---------------------------------------------------------------------

	public void setParent(ApplicationContext parent) {
		this.parent = parent;
	}

	/**
	 * Load or reload configuration.
	 */
	public void refresh() throws BeansException {
		this.startupTime = System.currentTimeMillis();

		refreshBeanFactory();
		getBeanFactory().ignoreDependencyType(ApplicationContext.class);
		getBeanFactory().addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		getBeanFactory().registerCustomEditor(Resource.class, new ContextResourceEditor(this));

		if (getBeanDefinitionCount() == 0) {
			logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
		}
		else {
			logger.info(getBeanDefinitionCount() + " beans defined in ApplicationContext [" + getDisplayName() + "]");
		}

		// invoke factory processors that can override values in the bean definitions
		invokeBeanFactoryPostProcessors();

		// register bean processor that intercept bean creation
		registerBeanPostProcessors();

		// initialize message source for this context
		initMessageSource();

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

		// check for listener beans and register them
		refreshListeners();

		// instantiate singletons this late to allow them to access the message source
		getBeanFactory().preInstantiateSingletons();

		// last step: publish respective event
		publishEvent(new ContextRefreshedEvent(this));
	}

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * Must be called before singleton instantiation.
	 */
	private void invokeBeanFactoryPostProcessors() throws BeansException {
		String[] beanNames = getBeanDefinitionNames(BeanFactoryPostProcessor.class);
		BeanFactoryPostProcessor[] factoryProcessors = new BeanFactoryPostProcessor[beanNames.length];
		for (int i = 0; i < beanNames.length; i++) {
			factoryProcessors[i] = (BeanFactoryPostProcessor) getBean(beanNames[i]);
		}
		Arrays.sort(factoryProcessors, new OrderComparator());
		for (int i = 0; i < factoryProcessors.length; i++) {
			BeanFactoryPostProcessor factoryProcessor = factoryProcessors[i];
			factoryProcessor.postProcessBeanFactory(getBeanFactory());
		}
	}

	/**
	 * Instantiate and invoke all registered BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * Must be called before singleton instantiation.
	 */
	private void registerBeanPostProcessors() throws BeansException {
		String[] beanNames = getBeanDefinitionNames(BeanPostProcessor.class);
		if (beanNames.length > 0) {
			List beanProcessors = new ArrayList();
			for (int i = 0; i < beanNames.length; i++) {
				beanProcessors.add(getBean(beanNames[i]));
			}
			Collections.sort(beanProcessors, new OrderComparator());
			for (Iterator it = beanProcessors.iterator(); it.hasNext();) {
				getBeanFactory().addBeanPostProcessor((BeanPostProcessor) it.next());
			}
		}
	}

	
	/**
	 * Template method which can be overridden to add context-specific refresh work.
	 * Called on initialization of special beans, before instantiation of singletons.
	 * @throws BeansException in case of errors during refresh
	 */
	protected void onRefresh() throws BeansException {
		// for subclasses: do nothing by default
	}

	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	private void refreshListeners() throws BeansException {
		logger.info("Refreshing listeners");
		Collection listeners = getBeansOfType(ApplicationListener.class, true, false).values();
		logger.debug("Found " + listeners.size() + " listeners in bean factory");
		for (Iterator it = listeners.iterator(); it.hasNext();) {
			ApplicationListener listener = (ApplicationListener) it.next();
			addListener(listener);
			logger.info("Application listener [" + listener + "] added");
		}
	}

	/**
	 * Add a listener. Any beans that are listeners are automatically added.
	 */
	protected void addListener(ApplicationListener l) {
		this.eventMulticaster.addApplicationListener(l);
	}

	/**
	 * Destroy the singletons in the bean factory of this application context.
	 */
	public void close() {
		logger.info("Closing application context [" + getDisplayName() + "]");

		// destroy all cached singletons in this context,
		// invoking DisposableBean.destroy and/or "destroy-method"
		getBeanFactory().destroySingletons();

		// publish respective event
		publishEvent(new ContextClosedEvent(this));
	}


	//---------------------------------------------------------------------
	// Implementation of BeanFactory
	//---------------------------------------------------------------------

	public Object getBean(String name) throws BeansException {
		return getBeanFactory().getBean(name);
	}

	public Object getBean(String name, Class requiredType) throws BeansException {
		return getBeanFactory().getBean(name, requiredType);
	}

	public boolean containsBean(String name) throws BeansException {
		return getBeanFactory().containsBean(name);
	}

	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
		return getBeanFactory().isSingleton(name);
	}

	public String[] getAliases(String name) throws NoSuchBeanDefinitionException {
		return getBeanFactory().getAliases(name);
	}


	//---------------------------------------------------------------------
	// Implementation of HierarchicalBeanFactory
	//---------------------------------------------------------------------

	public BeanFactory getParentBeanFactory() {
		return getParent();
	}


	//---------------------------------------------------------------------
	// Implementation of ListableBeanFactory
	//---------------------------------------------------------------------

	public int getBeanDefinitionCount() {
		return getBeanFactory().getBeanDefinitionCount();
	}

	public String[] getBeanDefinitionNames() {
		return getBeanFactory().getBeanDefinitionNames();
	}

	public String[] getBeanDefinitionNames(Class type) {
		return getBeanFactory().getBeanDefinitionNames(type);
	}

	public boolean containsBeanDefinition(String name) {
		return getBeanFactory().containsBeanDefinition(name);
	}

	public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException {
		return getBeanFactory().getBeansOfType(type, includePrototypes, includeFactoryBeans);
	}


	//---------------------------------------------------------------------
	// Implementation of AutowireCapableBeanFactory
	//---------------------------------------------------------------------

	public Object autowire(Class beanClass) throws BeansException {
		return getBeanFactory().autowire(beanClass);
	}

	public Object autowireConstructor(Class beanClass) throws BeansException {
		return getBeanFactory().autowireConstructor(beanClass);
	}

	public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
			throws BeansException {
		getBeanFactory().autowireBeanProperties(existingBean, autowireMode, dependencyCheck);
	}

	public Object applyBeanPostProcessors(Object existingBean, String name) throws BeansException {
		return getBeanFactory().applyBeanPostProcessors(existingBean, name);
	}




	/** Show information about this context */
	public String toString() {
		StringBuffer sb = new StringBuffer("ApplicationContext: displayName=[" + this.displayName + "]; ");
		sb.append("class=[" + getClass().getName() + "]; ");
		sb.append("beanFactory=[" + getBeanFactory() + "]; ");
		sb.append("messageSource=[" + this.messageSource + "]; ");
		sb.append("startup date=[" + new Date(this.startupTime) + "]; ");
		if (this.parent == null)
			sb.append("root of ApplicationContext hierarchy");
		else
			sb.append("parent=[" + this.parent + "]");
		return sb.toString();
	}


	//---------------------------------------------------------------------
	// Abstract methods that must be implemented by subclasses
	//---------------------------------------------------------------------

	
	protected abstract void refreshBeanFactory() throws BeansException;

	/**
	 * Subclasses must return their internal bean factory here.
	 * They should implement the lookup efficiently, so that it can be called
	 * repeatedly without a performance penalty.
	 * @return this application context's internal bean factory
	 */
	public abstract ConfigurableListableBeanFactory getBeanFactory();

}

 

8

 

public interface ConfigurableListableBeanFactory extends AutowireCapableBeanFactory, ConfigurableBeanFactory {

	/**
	 * Ensure that all non-lazy-init singletons are instantiated, also considering
	 * FactoryBeans. Typically invoked at the end of factory setup, if desired.
	 */
	void preInstantiateSingletons();

}

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值