登记beans要点方法摘取

来源:互联网 发布:大数据自学 编辑:程序博客网 时间:2024/05/16 01:56

一、beans加载
概要:bean的加载主要是由如下抽象类完成,beandefinition中的样子大体如下:

public abstract class AbstractApplicationContext extends DefaultResourceLoader        implements ConfigurableApplicationContext, DisposableBean {...}
Generic bean: class [com.bean.entities.Person]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null

1、类中变量声明详细

    /**     * Name of the MessageSource bean in the factory.     * If none is supplied, message resolution is delegated to the parent.     * @see MessageSource     */    public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";    /**     * Name of the LifecycleProcessor bean in the factory.     * If none is supplied, a DefaultLifecycleProcessor is used.     * @see org.springframework.context.LifecycleProcessor     * @see org.springframework.context.support.DefaultLifecycleProcessor     */    public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";    /**     * Name of the ApplicationEventMulticaster bean in the factory.     * If none is supplied, a default SimpleApplicationEventMulticaster is used.     * @see org.springframework.context.event.ApplicationEventMulticaster     * @see org.springframework.context.event.SimpleApplicationEventMulticaster     */    public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";    static {        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)        ContextClosedEvent.class.getName();    }    /** Logger used by this class. Available to subclasses. */    protected final Log logger = LogFactory.getLog(getClass());    /** Unique id for this context, if any */    private String id = ObjectUtils.identityToString(this);    /** Display name */    private String displayName = ObjectUtils.identityToString(this);    /** Parent context */    private ApplicationContext parent;    /** BeanFactoryPostProcessors to apply on refresh */    private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors =            new ArrayList<BeanFactoryPostProcessor>();    /** System time in milliseconds when this context started */    private long startupDate;    /** Flag that indicates whether this context is currently active */    private final AtomicBoolean active = new AtomicBoolean();    /** Flag that indicates whether this context has been closed already */    private final AtomicBoolean closed = new AtomicBoolean();    /** Synchronization monitor for the "refresh" and "destroy" */    private final Object startupShutdownMonitor = new Object();    /** Reference to the JVM shutdown hook, if registered */    private Thread shutdownHook;    /** ResourcePatternResolver used by this context */    private ResourcePatternResolver resourcePatternResolver;    /** LifecycleProcessor for managing the lifecycle of beans within this context */    private LifecycleProcessor lifecycleProcessor;    /** MessageSource we delegate our implementation of this interface to */    private MessageSource messageSource;    /** Helper class used in event publishing */    private ApplicationEventMulticaster applicationEventMulticaster;    /** Statically specified listeners */    private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();    /** Environment used by this context; initialized by {@link #createEnvironment()} */    private ConfigurableEnvironment environment;

2、bean加载主方法入口

  • javadoc文档

    Load or refresh the persistent representation of the configuration, which might an XML file, properties file, or relational database schema.

As this is a startup method, it should destroy already created singletons if it fails, to avoid dangling resources. In other words, after invocation of that method, either all or no singletons at all should be instantiated.

  • 源码
@Override    public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            // Prepare this context for refreshing.            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();                // Instantiate all remaining (non-lazy-init) singletons.                finishBeanFactoryInitialization(beanFactory);                // Last step: publish corresponding event.                finishRefresh();            }            catch (BeansException ex) {                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;            }        }    }

2.1、prepareRefresh(主要完成一些底层系统初始化操作)

  • javadoc
    Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources.

  • 源码

protected void prepareRefresh() {        this.startupDate = System.currentTimeMillis();        this.active.set(true);        if (logger.isInfoEnabled()) {            logger.info("Refreshing " + this);        }        // Initialize any placeholder property sources in the context environment        initPropertySources();        // Validate that all properties marked as required are resolvable        // see ConfigurablePropertyResolver#setRequiredProperties        getEnvironment().validateRequiredProperties();    }

2.2、obtainFreshBeanFactory (完成对bean的登记)

  • javadoc
    Tell the subclass to refresh the internal bean factory.

  • 源码

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {        refreshBeanFactory();        ConfigurableListableBeanFactory beanFactory = getBeanFactory();        if (logger.isDebugEnabled()) {            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);        }        return beanFactory;    }
  • 测试截图
    要点属性摘要

map信息摘要
bean定义信息

2.3、prepareBeanFactory(配置传入工厂的标准上下文性质,如:类加载器、后置处理器等)

  • javadoc
    Configure the factory’s standard context characteristics, such as the context’s ClassLoader and post-processors.
  • 源码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {        // Tell the internal bean factory to use the context's class loader etc.        beanFactory.setBeanClassLoader(getClassLoader());        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));        // Configure the bean factory with context callbacks.        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);        // BeanFactory interface not registered as resolvable type in a plain factory.        // MessageSource registered (and found for autowiring) as a bean.        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);        beanFactory.registerResolvableDependency(ResourceLoader.class, this);        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);        beanFactory.registerResolvableDependency(ApplicationContext.class, this);        // Detect a LoadTimeWeaver and prepare for weaving, if found.        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            // Set a temporary ClassLoader for type matching.            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }        // Register default environment beans.        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());        }        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());        }        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());        }    }

2.4、postProcessBeanFactory(模板设计,以供继承该抽象的子类对BeanFactory修改、校验等等操作)

  • javadoc
    Modify the application context’s internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for registering special BeanPostProcessors etc in certain ApplicationContext implementations.

  • 源码

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {    }

2.5、invokeBeanFactoryPostProcessors()

  • javadoc
    Instantiate and invoke all registered BeanFactoryPostProcessor beans, respecting explicit order if given.
    Must be called before singleton instantiation.

  • 源码

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());    }

2.6、registerBeanPostProcessors()

  • javadoc
    Instantiate and invoke all registered BeanPostProcessor beans, respecting explicit order if given.
    Must be called before any instantiation of application beans.

  • 源码

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);    }

2.7、initMessageSource()

  • javadoc
    Initialize the MessageSource. Use parent’s if none defined in this context.

  • 源码

protected void initMessageSource() {        ConfigurableListableBeanFactory beanFactory = getBeanFactory();        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);            // Make MessageSource aware of parent MessageSource.            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;                if (hms.getParentMessageSource() == null) {                    // Only set parent context as parent MessageSource if no parent MessageSource                    // registered already.                    hms.setParentMessageSource(getInternalParentMessageSource());                }            }            if (logger.isDebugEnabled()) {                logger.debug("Using MessageSource [" + this.messageSource + "]");            }        }        else {            // Use empty MessageSource to be able to accept getMessage calls.            DelegatingMessageSource dms = new DelegatingMessageSource();            dms.setParentMessageSource(getInternalParentMessageSource());            this.messageSource = dms;            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);            if (logger.isDebugEnabled()) {                logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +                        "': using default [" + this.messageSource + "]");            }        }    }

2.8、initApplicationEventMulticaster()

  • javadoc
    Initialize the ApplicationEventMulticaster. Uses SimpleApplicationEventMulticaster if none defined in the context.
  • 源码
protected void initApplicationEventMulticaster() {        ConfigurableListableBeanFactory beanFactory = getBeanFactory();        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {            this.applicationEventMulticaster =                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);            if (logger.isDebugEnabled()) {                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");            }        }        else {            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);            if (logger.isDebugEnabled()) {                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +                        "': using default [" + this.applicationEventMulticaster + "]");            }        }    }

2.9、onRefresh()

  • javadoc
    Template method which can be overridden to add context-specific refresh work. Called on initialization of special beans, before instantiation of singletons.
    This implementation is empty.

  • 源码

    protected void onRefresh() throws BeansException {        // For subclasses: do nothing by default.    }

2.10、registerListeners()

  • javadoc
    Add beans that implement ApplicationListener as listeners. Doesn’t affect other listeners, which can be added without being beans.

  • 源码

protected void registerListeners() {        // Register statically specified listeners first.        for (ApplicationListener<?> listener : getApplicationListeners()) {            getApplicationEventMulticaster().addApplicationListener(listener);        }        // Do not initialize FactoryBeans here: We need to leave all regular beans        // uninitialized to let post-processors apply to them!        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);        for (String lisName : listenerBeanNames) {            getApplicationEventMulticaster().addApplicationListenerBean(lisName);        }    }

2.11、finishBeanFactoryInitialization()

  • javadoc
    Finish the initialization of this context’s bean factory, initializing all remaining singleton beans.
  • 源码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        // Initialize conversion service for this context.        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {            beanFactory.setConversionService(                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));        }        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        for (String weaverAwareName : weaverAwareNames) {            getBean(weaverAwareName);        }        // Stop using the temporary ClassLoader for type matching.        beanFactory.setTempClassLoader(null);        // Allow for caching all bean definition metadata, not expecting further changes.        beanFactory.freezeConfiguration();        // Instantiate all remaining (non-lazy-init) singletons.        beanFactory.preInstantiateSingletons();    }

2.12、finishRefresh()

  • javadoc
    Finish the refresh of this context, invoking the LifecycleProcessor’s onRefresh() method and publishing the org.springframework.context.event.ContextRefreshedEvent.

  • 源码

    protected void finishRefresh() {        // Initialize lifecycle processor for this context.        initLifecycleProcessor();        // Propagate refresh to lifecycle processor first.        getLifecycleProcessor().onRefresh();        // Publish the final event.        publishEvent(new ContextRefreshedEvent(this));        // Participate in LiveBeansView MBean, if active.        LiveBeansView.registerApplicationContext(this);    }
0 0