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();
}