`

spring初始化

 
阅读更多
很多人看开源框架源代码的时候都不知道从哪里入手,我这里推荐一个最简单的办法,写一个最简单的应用的例子,然后根据这个应用一点一点查看在源码中的运行步骤,这样就能对框架有一个基本的了解,有了这个基本的认识,再去针对不同模块扩展开来仔细研究。
 
本系列主要是学习spring的源码,首先是最简单的使用例子:
1
2
3
ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "spring-config.xml");
FooService foo = (FooService) ctx.getBean("FooService");

我们看第一行初始化了一个ClassPathXmlApplicationContext对象,

注:也可以用FileSystemXmlApplicationContext来加载,两者的区别只是查找配置文件的起始路径不同,一个以classpath为当前路径,一个是直接用文件系统的当前路径,内部没有太大区别。

注2:web工程大家都知道我们配置了ContextLoaderListener,这里暂时不做介绍,后面会有专门的分析,起始主题流程都差不多,详情请参见:从源码看Spring在web工程中的初始化。

请看下面的构造方法,参数是spring配置文件在classpath中的全路径名:

1
2
3
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

可以看到里面调用了另外一个构造方法(如下),其中传递了两个默认参数refresh=true立即刷新,parent=null继承为空,并且把配置文件封装为了一个String数组,这里主要是因为spring是支持多个配置文件的

1
2
3
4
5
6
7
8
9
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
  
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

我们看这个构造方法的代码:

  • 首先调用了父类的构造函数
  • 调用setConfigLocations设置配置文件位置信息(代码如下)
  • 判断如果refresh为true则调用refresh()方法,refresh方法在AbstractApplicationContext中

setConfigLocations代码:
很简单,主要是检验是否传入参数为空然后赋值给configLocations属性,不过其中有两个小特点可以注意一下:

  1. 并没有直接把传入参数locations直接赋值给属性,而是new了一个String数组,然后循环赋值,这里主要是出于安全考虑避免外面传入的字符串数组变化影响spring内部
  2. 可以看到赋值前有调用了一下resolvePath方法,这个方法实现了一些系统变量的替换,例如路径里可以使用${}加载系统变量值
1
2
3
4
5
6
7
8
9
10
11
12
public void setConfigLocations(String[] locations) {
    if (locations != null) {
        Assert.noNullElements(locations,
                "Config locations must not be null");
        this.configLocations = new String[locations.length];
        for (int i = 0; i < locations.length; i++) {
            this.configLocations[i] = resolvePath(locations[i]).trim();
        }
    } else {
        this.configLocations = null;
    }
}

 

下面看refresh刷新方法,这个刷新方法主要是从配置文件加载bean配置的过程,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public void refresh() throws BeansException, IllegalStateException {
    // 整个刷新过程是同步的
    synchronized (this.startupShutdownMonitor) {
        // 刷新前的准备工作
        prepareRefresh();
        // 关闭释放旧的beanFactory创建新的beanFactory,读取配置文件等
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 对beanFactory进行一些基本的初始化
        prepareBeanFactory(beanFactory);
  
        try {
            // 下面两行主要用户扩展,处理所有已注册的BeanFactoryPostProcessor,实现在已经加载配置但未初始化bean时对配置进行修改
            postProcessBeanFactory(beanFactory);
            invokeBeanFactoryPostProcessors(beanFactory);
            // 处理所有已注册的BeanPostProcessor,主要用于扩展,实现bean初始化前后的一些定制操作
            registerBeanPostProcessors(beanFactory);
  
            // 初始化消息源bean
            initMessageSource();
            // 初始化事件监听器集,也有人叫事件监听器的注册表,所有的事件监听器都在这个bean里进行管理
            initApplicationEventMulticaster();
            // 主要用于扩展,实现一些特殊bean的初始化,时间点是类似消息源事件监听器集等特殊bean初始化后,普通的bean初始化前
            onRefresh();
            // 注册监听器
            registerListeners();
            // 初始化其余的非延迟加载的单例bean
            finishBeanFactoryInitialization(beanFactory);
  
            // 刷新完成调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件
            finishRefresh();
        } catch (BeansException ex) {
            // 销毁已经创建的单例bean
            destroyBeans();
            // 重新设置active标记
        cancelRefresh(ex);
            throw ex;
        }
    }
}

上面是一个spring初始化的基本流程框架,后面几篇将陆续对其中每一个方法进行详细的分析

 

上篇结束的地方简单介绍了一下refresh()方法,现在我们具体分析一下它的代码细节:

1.首先可以看到整个refresh()的代码都是同步的,对应的同步对象是startupShutdownMonitor,我们看一下startupShutdownMonitor引用的地方,可以知道,只有在refresh()和close()两个方法里用到,说明这个锁是用来同步applicationContext的刷新和销毁的。

2.同步代码块的第一行是prepareRefresh()方法,代码如下:

1
2
3
4
5
6
7
8
9
protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    synchronized (this.activeMonitor) {
        this.active = true;
    }
    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }
}

这个方法也很简单

  1. 首先设置startupDate为系统当前毫秒数,代表当前applicationContext的创建时间;
  2. 设置active为true,代表当前applicationContext是活动的,可以看到对active的赋值操作是同步的,同步对象为activeMonitor,查看active的引用点,可以看到所有对 active的操作都是同步在activeMonitor下的,在调用cancelRefresh()和doClose()两个方法的时候会把它设置为false,其中cancelRefresh()代表中止refresh,doClose()则是当前applicationContext的关闭销毁方法
  3. 最后是日志的打印,info级别,我这里要说的一点是后面直接+this,代表会调用toString方法,AbstractApplicationContext重写了toString,大概格式是displayName+startup+parent displayName

3.接着是这一行:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),obtainFreshBeanFactory代码如下:

1
2
3
4
5
6
7
8
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

第一行调用refreshBeanFactory(),我们先跳过这行看下面,调用了getBeanFactory()获得beanFactory对象然后返回这个对象,看getBeanFactory()的代码可以看到,是做了一个同步,然后取出当前对象里的beanFactory,同步锁是beanFactoryMonitor:

注:refreshBeanFactory()和getBeanFactory()方法在AbstractRefreshableApplicationContext类里面,关于ApplicationContext的类结构我会在另外一篇文章里做专门介绍,请看:ApplicationContext的类继承结构及框架图

1
2
3
4
5
6
7
8
9
public final ConfigurableListableBeanFactory getBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
        if (this.beanFactory == null) {
            throw new IllegalStateException("BeanFactory not initialized or already closed - " +
                    "call 'refresh' before accessing beans via the ApplicationContext");
        }
        return this.beanFactory;
    }
}

如果beanFactory为空则会抛出异常,其实一开始beanFactory肯定是null的,beanFactory的创建就是在refreshBeanFactory()方法中,下面我们看它的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

前面3行代码首先判断是否hasBeanFactory(),如果存在则调用destroyBeans()以及closeBeanFactory():

  • hasBeanFactory()是在判断属性beanFactory是否为空,当然同上面一样beanFactory的操作是同步的,同步对象是beanFactoryMonitor。
  • destroyBeans()方法只有一行代码:getBeanFactory().destroySingletons(),调用了beanFactory对象的destroySingletons()方法来销毁所有单例bean。(后面还会用到这个方法,放到后面详细介绍)
  • closeBeanFactory()和上面一样,依旧是同步的情况下处理beanFactory属性,首先调用setSerializationId(null),然后把beanFactory属性设置为null。

接下来后面的代码是一个创建beanFactory的过程:

  • 调用createBeanFactory()方法创建一个beanFactory对象:
    查看方法代码可以看到创建的是一个DefaultListableBeanFactory对象,参数parent传递的方法getInternalParentBeanFactory()返回的结果,getInternalParentBeanFactory()方法的代码为:
    (getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent()
    如果当前applicationContext对象的parent是ConfigurableApplicationContext类的实例则返回当前对象的parent的beanFactory对象,否则直接返回当前对象的parent。
     
  • 将当前对象的id属性作为参数调用为beanFactory对象的setSerializationId()方法,我们这里看下这个方法的代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void setSerializationId(String serializationId) {
        if (serializationId != null) {
            serializableFactories.put(serializationId,
                    new WeakReference<DefaultListableBeanFactory>(this));
        } else if (this.serializationId != null) {
            serializableFactories.remove(this.serializationId);
        }
        this.serializationId = serializationId;
    }
    首先,输入参数如果不为空执行(1),否则再判断如果当前对象的属性serializationId不为空,执行(2)
    (1)在serializableFactories里加入一组值:键为serializationId,值为当前对象的弱引用
    (2)从serializableFactories中移除键为当前对象属性serializationId的对象,也就是以前存入的当前对象的弱引用
    (3)设置属性serializationId为输入参数
     
  • customizeBeanFactory()方法的代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }
        beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
        beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
    }
    如果属性allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性,此属性的含义:是否允许覆盖同名称的不同定义的对象
    如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性,此属性的含义:是否允许bean之间循环引用
    设置beanFactory的parameterNameDiscoverer属性为一个新的LocalVariableTableParameterNameDiscoverer对象,主要用asm解析class文件
    设置beanFactory的parameterNameDiscoverer属性为一个新的QualifierAnnotationAutowireCandidateResolver对象,主要用于自动装配的处理
     
  • loadBeanDefinitions()方法的代码:
    1
    2
    3
    4
    5
    6
    7
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }
    第1行创建XmlBeanDefinitionReader对象
    第2行设置beanDefinitionReader的resourceLoader属性为当前对象
    第3行设置beanDefinitionReader的entityResolver属性为一个新的ResourceEntityResolver对象,输入参数resourceLoader为当前对象,这个数要是用来解析xml的
    第4行设置beanDefinitionReader的validationMode以及namespaceAware,参数是当前对象的validating属性,主要用于xml校检
    最后一行是做了xml配置文件的读取,就不做详细描述了,有个细节是会循环加载configResources、configLocations两个里面的文件
     
  • 接着是同步操作beanFactory,把创建的beanFactory对象赋值给当前ApplicationContext的beanFactory属性

refresh()方法中在上篇obtainFreshBeanFactory()方法创建了beanfactory对象,之后的代码就开始是对beanFactory对象的一些处理,BeanFactory相关的一些内容也是spring的核心内容。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、首先是prepareBeanFactory(beanFactory),主要是做了一些beanFactory的初始化工作,因为这个方法比较长,我们分成4部分来看,

第1部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  • 第1行设置beanFactory的classLoader为当前context的classLoader
  • 第2行设置beanFactory的表达式语言处理器,spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值。
  • 第3行为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具,以后再做详细分析。
  • 第4行添加了一个处理aware相关接口的beanPostProcessor扩展,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能,aware接口是用来给bean注入一些资源的接口,例如实现BeanFactoryAware的Bean在初始化后,Spring容器将会注入BeanFactory的实例相应的还有ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等。
  • 第5-8行设置了几个忽略自动装配的接口,默认只有BeanFactoryAware被忽略,其他的都要自行设置,这里设置了ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware。
  • 第9-12行设置了几个自动装配的特殊规则,如果是BeanFactory类型,则注入beanFactory对象,如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext类型则注入当前对象(applicationContext对象)。

第2部分代码:

1
2
3
4
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
  • 这部分判断是否定义了名为loadTimeWeaver的bean,如果定义了则添加loadTimeWeaver功能的beanPostProcessor扩展,并且创建一个临时的classLoader来让其处理真正的bean。spring的loadTimeWeaver主要是通过 instrumentation 的动态字节码增强在装载期注入依赖。具体这部分还没有很好的理解,暂时标记一下以后再专门研究看看。

第3部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    Map systemProperties;
    try {
        systemProperties = System.getProperties();
    } catch (AccessControlException ex) {
        systemProperties = new ReadOnlySystemAttributesMap() {
            protected String getSystemAttribute(String propertyName) {
                try {
                    return System.getProperty(propertyName);
                } catch (AccessControlException ex) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Not allowed to obtain system property [" + propertyName + "]: " +
                                ex.getMessage());
                    }
                    return null;
                }
            }
        };
    }
    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
}
  • 这部分首先判断是否定义了名为systemProperties的bean,如果没有则加载系统获取当前系统属性System.getProperties()并注册为一个单例bean。假如有AccessControlException权限异常则创建一个ReadOnlySystemAttributesMap对象,可以看到创建时重写了getSystemAttribute()方法,查看ReadOnlySystemAttributesMap的代码可以得知在调用get方法的时候会去调用这个方法来获取key对应的对象,当获取依旧有权限异常AccessControlException的时候则返回null。

第4部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    Map<String,String> systemEnvironment;
    try {
        systemEnvironment = System.getenv();
    } catch (AccessControlException ex) {
        systemEnvironment = new ReadOnlySystemAttributesMap() {
            protected String getSystemAttribute(String variableName) {
                try {
                    return System.getenv(variableName);
                } catch (AccessControlException ex) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Not allowed to obtain system environment variable [" + variableName + "]: " +
                                ex.getMessage());
                    }
                    return null;
                }
            }
        };
    }
    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
}
  • 这部分和上面一部分类似,只不过由系统属性改为了系统环境变量,异常处理方式等也和上面一部分一样。这两部分都是为spring内部提供系统信息的支撑bean。

 

二、prepareBeanFactory()方法调用之后,是一个try-catch代码块,如果有BeanException异常产生则会停止refresh并且销毁已创建的资源,现在看代码块里的第一行postProcessBeanFactory(beanFactory)

postProcessBeanFactory()方法,默认方法体是空的,主要是用来扩展beanfactory的,扩展点是在bean等配置都已经加载但还没有进行实例化的时候。

例如上面说到的aware相关接口自动装配设置,假如是web项目,使用的是spring的webApplicationcontext,这时需要一些ServletContextAware相关的自动装配忽略及配置等,就需要在webApplicationContext里重写这个方法来实现相应功能。

 

refresh()方法中在上篇看到了postProcessBeanFactory(beanFactory),这篇继续往下看。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、invokeBeanFactoryPostProcessors(beanFactory),这个方法从名字就可以看出是在调用BeanFactoryProcessor,代码也比较长,分成几部分来看。

第1部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
            new LinkedList<BeanDefinitionRegistryPostProcessor>();
    for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryPostProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
            registryPostProcessors.add(registryPostProcessor);
        }
        else {
            regularPostProcessors.add(postProcessor);
        }
    }
    Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
            beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
            new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
    OrderComparator.sort(registryPostProcessorBeans);
    for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
    invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    processedBeans.addAll(beanMap.keySet());
}
else {
    invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
  • 首先创建一个HashSet变量processedBeans,接着是个判断,如果beanFactory类型实现了BeanDefinitionRegistry接口,强转beanFactory对象为BeanDefinitionRegistry类型变量registry,创建两个LinkedList变量regularPostProcessors用来存储普通PostProcessor;registryPostProcessors用来存储一些用来对bean定义的注册信息进行处理的PostProcessor。
  • 7-17行循环所有applicationContext中已经注册的BeanFactoryPostProcessor,如果是实现了BeanDefinitionRegistryPostProcessor的类型,则调用对应的postProcessBeanDefinitionRegistry()方法进行相应处理并加入到registryPostProcessors中,否则加入到regularPostProcessors中。
  • 18-25行首先调用BeanFactory的getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)方法获取所有类型为BeanDefinitionRegistryPostProcessor的bean,然后放到List对象registryPostProcessorBeans中并且进行排序,排序之后循环调用每个bean的postProcessBeanDefinitionRegistry()方法。
    注:getBeansOfType()后续会有一个针对beanFactory的专门研究先不做详细分析,这里简单说一下排序,spring内部实现了一套排序方法,主要是一个Ordered接口,需要排序的对象实现这个接口的getOrder()方法,在进行排序的时候会对这个结果进行比较从而实现排序。另外假如某个对象实现的是PriorityOrdered接口则优先进行排序,同样情况则依旧比较getOrder()的结果。
  • 26-28行依次对3个List对象调用invokeBeanFactoryPostProcessors()方法,进行BeanFactoryPostProcessor的处理,顺序为registryPostProcessors、registryPostProcessorBeans、regularPostProcessors。invokeBeanFactoryPostProcessors()方法的代码很简单,就是for循环调用每个postProcessor对象的postProcessBeanFactory(beanFactory)方法。
  • 29行把所有bean中加载过来的BeanDefinitionRegistryPostProcessor类型的bean的名字加入到processedBeans中。
  • 回到上面最开始的判断,如果beanFactory类型没有实现BeanDefinitionRegistry接口,则直接调用invokeBeanFactoryPostProcessors()方法处理所有ApplicationContext已注册的BeanFactoryPostProcessor。

第2部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
    if (processedBeans.contains(ppName)) {
        // skip - already processed in first phase above
    }
    else if (isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    else if (isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    }
    else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
    orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
    nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  • 第1、2行首先获取所有类型为BeanFactoryPostProcessor的bean的name集合放到变量postProcessorNames
  • 第3行建立一个ArrayList变量priorityOrderedPostProcessors用来存储需优先处理的postProcessor
  • 第4、5行分别建立两个ArrayList变量orderedPostProcessorNames、nonOrderedPostProcessorNames用来存储有排序的和无排序的postProcessor
  • 第6-19行循环上面获取到的所有postProcessor的name集合,按条件进行不同处理:
        如果name已经存在于processedBeans则代表是已经处理过了,跳过这一个;
        调用isTypeMatch()方法根据bean的name判断该bean是否实现了PriorityOrdered接口(上面我们说过排序中这个属于优先排序),如果是的话根据该name取出对应的bean对象加入到priorityOrderedPostProcessors集合中;
        调用isTypeMatch()方法根据bean的name判断该bean是否实现了Ordered接口(上面我们说过实现了这个接口就可以进行排序了),如果是的话把该name加入到orderedPostProcessorNames集合中;
        如果都上面条件都不成立,则加入到nonOrderedPostProcessorNames集合中;
    注:关于isTypeMatch()方法,说起来简单就是根据bean的name取出bean对象然后进行类型判断,但实际上这个方法并不简单,最终主逻辑代码在AbstractBeanFactory中,做个标记,以后单独抽出来分析一下。
  • 第20行对priorityOrderedPostProcessors进行排序
  • 第21行调用invokeBeanFactoryPostProcessors()方法对priorityOrderedPostProcessors中的所有postProcessor进行处理
  • 第23-28行通过getBean()方法取得所有orderedPostProcessorNames集合中postProcessor的bean对象,然后加入到一个新的集合变量orderedPostProcessors中,然后对这个集合排序,最后调用invokeBeanFactoryPostProcessors()方法处理
  • 后面的一部分是对无排序的nonOrderedPostProcessorNames进行处理,除了去掉排序步骤之外和上面的步骤一样,就不重复描述了

二、我们回到refresh()方法中,看下一行:registerBeanPostProcessors(beanFactory),这个方法主要就是对BeanPostProcessor的注册,依旧分为几部分来看:

第1部分:

1
2
3
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
  • 第1行获取所有的BeanPostProcessor类型的bean的name数组
  • 第2行计算BeanPostProcessor的数量:banFactory中已注册的BeanPostProcessor的数量 + 1 + 上面获取到的所有bean中的BeanPostProcessor的数量。这里面的那个+1,是下一行的BeanPostProcessorChecker
  • 第3行注册一个BeanPostProcessorChecker到beanFactory中,这个BeanPostProcessor作用是当一个bean创建后没有被所有的BeanPostProcessor处理的时候打印一行info级别日志

 

第2部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
    if (isTypeMatch(ppName, PriorityOrdered.class)) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    else if (isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    }
    else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}
  • 这部分代码与BeanFactoryPostProcessor的处理那部分类似,就是把所有的BeanPostProcessor进行区分放到不同集合里,优先的、排序的、无排序的。有个特殊的地方就是多了一个internalPostProcessors集合,用来存放优先级别中类型为MergedBeanDefinitionPostProcessor的BeanPostProcessor。它的主要作用是在spring运行时合并处理bean定义,例如注解中的bean定义,这部分也还没完全弄清楚,做个标记,回头专项分析。

第3部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
  
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    orderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
  
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
  
OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
  
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
  • 第1-2行对priorityOrderedPostProcessors进行排序,并调用registerBeanPostProcessors()方法进行注册处理,这个方法内部代码比较简单,就是循环这个集合并调用beanFactory.addBeanPostProcessor(postProcessor)把每个BeanPostProcessor注册到beanFactory。
  • 第3-13行和之前也类似了,把所有orderedPostProcessorNames中的BeanPostProcessor取出来放到集合里,其中MergedBeanDefinitionPostProcessor类型的依旧加入到internalPostProcessors中。最后两行先排序,再调用registerBeanPostProcessors()方法进行注册处理
  • 第14-23行是对nonOrderedPostProcessorNames的处理,相比上面去掉了排序过程,其他依旧。
  • 紧接着的是对internalPostProcessors排序,注册处理。
  • 最后一行注册了一个BeanPostProcessor:ApplicationListenerDetector,这个是AbstractApplicationContext的内部类,实现了MergedBeanDefinitionPostProcessor接口,这个类只是暂时知道是在处理ApplicationListener相关的东西,具体作用还未知,留待分析。

refresh()方法中在上篇看完了对PostProcessors的处理,这篇继续往下看。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、initMessageSource(),这个方法是对spring的MessageSource初始化,代码如下:

1
2
3
4
5
6
7
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
    //第1部分
}
else {
    //第2部分
}
  • 首先获取beanFactory对象,然后判断是否定义了名为messageSource的localbean,如果有则执行第1部分,否则执行第2部分,分别来看两部分代码
    注:localbean实际上就是指查找的时候不会去parent查找这个bean,只从当前beanfactory去查找,很多地方有这个就不一一注明了

第1部分:

1
2
3
4
5
6
7
8
9
10
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
    HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
    if (hms.getParentMessageSource() == null) {
        hms.setParentMessageSource(getInternalParentMessageSource());
    }
}
if (logger.isDebugEnabled()) {
    logger.debug("Using MessageSource [" + this.messageSource + "]");
}
  • 第1行获取名为messageSource的bean赋值给当前ApplicationContext对象的messageSource属性
  • 第2行判断如果当前ApplicationContext的parent不为null;并且messageSource对象继承了HierarchicalMessageSource接口则进行如下处理:
        进行判断如果messageSource的parentMessageSource为空,则设置为getInternalParentMessageSource()方法的返回值。getInternalParentMessageSource()方法的代码也很简单
        (getParent() instanceof AbstractApplicationContext) ? ((AbstractApplicationContext) getParent()).messageSource : getParent()
        如果当前ApplicationContext的parent对象是AbstractApplicationContext或其子类类型则返回它的messageSource,否则直接返回其parent对象
  • 最后是打印一行debug级别日志表示当前应用的messageSource

 

第2部分:

1
2
3
4
5
6
7
8
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 + "]");
}
  • 第1行创建一个DelegatingMessageSource对象dms
  • 第2行类似上面,设置dms的parentMessageSource为getInternalParentMessageSource()返回值
  • 第3行设置当前ApplicationContext的messageSource属性为dms
  • 第4行把这个对象注册一个名为messageSource的单例bean
  • 打印一行debut日志表示无用户定义messageSource,使用默认

 

二、紧接着处理完messageSource的初始化后下一行代码:initApplicationEventMulticaster(),主要是对spring的事件监听器的管理器的初始话,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 + "]");
    }
}
  • 和messageSource的处理类似,首先取得beanFactory对象,
  • 判断如果用户主动定义了applicationEventMulticaster的bean,则把这个bean设置给applicationEventMulticaster属性
  • 如果没有则初始话一个默认的SimpleApplicationEventMulticaster,注册bean并赋值给对应属性
  • 不同情况分别打印不同的日志,源代码中的日志打印最好也稍微注意一下有个印象,这样在看spring的日志时会更清晰

 

三、接下来是一个模板方法onRefresh(),第一篇中提到过这个是在处理messageSource、applicationEventMulticaster等特殊bean后,普通单例bean没初始话之前,为ApplicationContext子类提供扩展去处理一些类似的特殊bean。

    举个例子AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext中都有一个themeSource,这个就要放在这个方法里去初始化。这个themeSource是spring的主题功能,可以实现根据不同主题加载不同资源文件等功能。

 

四、上面处理了事件监听器的管理器初始化,现在开始做时间监听器的注册:registerListeners(),这个方法的代码如下:

1
2
3
4
5
6
7
8
for (ApplicationListener listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
}
  
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
    getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
  • 上面3行是处理当前ApplicationContext中的静态特殊监听器集合,循环调用applicationEventMulticaster的addApplicationListener()方法注册到applicationEventMulticaster中
  • 后面的一部分首先取出所有类型为ApplicationListener的bean的name集合,然后循环调用applicationEventMulticaster的addApplicationListenerBean()方法注册到applicationEventMulticaster中
  • 注意上面两个注册方法的不同,分别会注册到applicationEventMulticaster.defaultRetriever的不同集合中

 

本篇分别看到了messageSource、applicationEventMulticaster和applicationListener以及中间提到的主题themeSource的初始化,这里主要介绍初始话,所以后续再对spring的这几个功能模块做分别详细的分析。

refresh()方法中在上篇看完了MessageSource及时间监听器等初始话处理,这篇继续往下看。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、finishBeanFactoryInitialization(beanFactory)这个方法将完成BeanFactory的初始化,主要做的事就是初始化除了之前处理过的特殊bean之外的所有单例bean,代码如下:

1
2
3
4
5
6
7
8
9
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));
}
  
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
  • 第1-5行判断如果定义了名为conversionService并且类型为ConversionService的bean,则把其设置为beanFactory的conversionService属性。这个主要是用来提供数据转化服务的
  • 销毁之前在prepareBeanFactory()中生成的临时ClassLoader
  • freezeConfiguration()的代码如下:
    1
    2
    3
    4
    this.configurationFrozen = true;
    synchronized (this.beanDefinitionMap) {
        this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
    }
    这个方法就是代表bean定义等配置已经可以缓存了,不会再有其他地方对其做修改了
  • 最后一行就是对所有非延迟加载的单例bean进行初始化了我们来看下这个方法的代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    if (this.logger.isInfoEnabled()) {
        this.logger.info("Pre-instantiating singletons in " + this);
    }
    synchronized (this.beanDefinitionMap) {
        for (String beanName : this.beanDefinitionNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            public Boolean run() {
                                return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit(); 
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
    }
    首先是一行info级别的日志,然后在对象beanDefinitionMap的同步下循环所有bean的name分别进行初始化
    首先获取bean定义信息对象bd,然后进行判断,这里只对非抽象bean(抽象bean是用于继承定义配置等信息的不可初始化)、单例、非延迟加载的bean进行处理
    判断如果是FactoryBean则进行下面的处理,如果不是直接调用getBean(beanName),这个方法调用会进行这个bean的初始化,关于这个方法还是放到BeanFactory的单独分析里面这里就不往里看了。
    对于FactoryBean的获取,要在beanname前加上一个&,然后会先判断是否是SmartFactoryBean并且渴望初始化(EagerInit),如果是才调用getBean(beanName),否则这个应该是在第一次调用工厂的getObject的时候才初始化
    注:对于这中间AccessController.doPrivileged的运用没有搞明白,留待以后分析,不知道为什么要在这里使用这个

二、最后的一个处理是finishRefresh()方法,代码如下:

1
2
3
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
publishEvent(new ContextRefreshedEvent(this));

1.先看initLifecycleProcessor()方法的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
    this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
    if (logger.isDebugEnabled()) {
        logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
    }
}
else {
    DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
    defaultProcessor.setBeanFactory(beanFactory);
    this.lifecycleProcessor = defaultProcessor;
    beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
    if (logger.isDebugEnabled()) {
        logger.debug("Unable to locate LifecycleProcessor with name '" +
                LIFECYCLE_PROCESSOR_BEAN_NAME +
                "': using default [" + this.lifecycleProcessor + "]");
    }
}

这个方法主要是用来初始化生命周期管理器LifecycleProcessor的

  • 如果用户定义了名为lifecycleProcessor类型为LifecycleProcessor的LocalBean,则赋值给当前ApplicationContext的lifecycleProcessor属性
  • 如果用户没有定义,则初始化默认的生命周期管理器DefaultLifecycleProcessor,注册单例bean,并赋值给lifecycleProcessor属性

2.initLifecycleProcessor()方法之后则是对生命周期管理器的触发,LifecycleProcessor有两个触发点onRefresh()和onClose(),当前正处于refresh所以调用其onRefresh()方法

3.调用publishEvent()方法发布ContextRefreshedEvent事件,publishEvent()的代码也很简单就不介绍了,就是调用当前上下文及parent的ApplicationEventMulticaster的multicastEvent()方法,这个放到分析事件处理模块时再去详细分析。

 

三、最后分析一下在整个try代码块中如果抛出异常的处理,可以看到分为了两个方法调用:

1.destroyBeans()代码很简单,就是调用BeanFactory的destroySingletons()方法销毁所有单例bean。还是暂不细看放到BeanFactory专项分析里去

2.cancelRefresh()这个方法代码看一下:

1
2
3
synchronized (this.activeMonitor) {
    this.active = false;
}

就是在同步下设置状态值而已,但是有个小细节,这个方法在AbstractRefreshableApplicationContext和GenericApplicationContext两个子类中进行了重写,但是也很简单,就是增加了一个beanFactory.setSerializationId(null)然后依旧调用上面super中的方法进行修改状态

 

关于ApplicationContext的基本初始化的过车这就分析完了,中间碰到了很多问题,也还有很多地方需要详细研究,下面列举备忘一下,后面挨个分析:

  1. bean定义的加载
  2. bean的初始化
  3. BeanFactory的一些核心方法
  4. BeanFactory和ApplictionContext的关系以及各自的类继承框架
  5. 扩展点BeanFactoryPostProcessor及BeanPostProcessor
  6. 事件监听器ApplicationListener
  7. 信息管理器MessageSource
  8. 属性编辑器PropertyEditor
  9. 生命周期管理器LifecycleProcessor
  10. 还有几个小细节例如LoadTimeWeaver、MergedBeanDefinitionPostProcessor、AccessController.doPrivileged等
分享到:
评论

相关推荐

    spring初始化过程

    beanFactory.preInstantiateSingletons()的初始化过程详解,包含了所有的调用过程。

    详解Spring 中如何控制2个bean中的初始化顺序

    Spring 中控制 2 个 bean 的初始化顺序 在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 ...

    SpringBoot项目启动时实现调用一次初始化方法.docx

    Spring初始化参数的顺序是: 1. 对象初始化——构造方法 2. 对象初始化——`@PostConstruct`注解的方法 3. 对象初始化——实现了`InitializingBean`接口的`afterPropertiesSet`方法 4. 对象初始化——自定义的`init`...

    Spring Bean创建初始化流程.docx

    在Spring框架中,Bean的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...

    干净的spring初始化工程,包含ioc,di,datasource,但是不包含aop

    在这个“干净的spring初始化工程”中,我们主要关注的是IOC和DI,而不涉及AOP。 **依赖注入(Dependency Injection,DI)**是Spring的核心特性之一,它简化了组件之间的依赖关系管理。在传统的Java应用中,对象通常...

    Spring初始化和销毁的实现方法

    "Spring初始化和销毁的实现方法" Spring框架中,Bean的初始化和销毁是非常重要的两个生命周期过程。今天我们将讨论Spring中 Bean 的初始化和销毁的实现方法。 1. 通过@Bean指定init-method和destroy-method 在 ...

    Spring中初始化泛型类的方法实例

    那么Spring初始化的`Processor&lt;T&gt;`将会是`Processor&lt;String&gt;`: ```java Processor&lt;String&gt; processor = new Processor(); processor.service = new StringService(); ``` 如果`Service&lt;T&gt;`是`NumberService...

    Spring bean初始化及销毁你必须要掌握的回调方法.docx

    下面将详细介绍如何通过不同方式定义Spring Bean的初始化和销毁回调方法。 **初始化回调方法** 1. **@PostConstruct注解** 这个Java标准注解用于标记一个方法,该方法将在对象完全构造后但在业务逻辑执行前被调用...

    Spring 源码分析(Bean的初始化)

    在Spring框架中,Bean的初始化是一个至关重要的过程,它涉及到从XML配置文件或者注解中读取Bean的定义,解析并构建Bean实例。本篇文章主要分析了Spring如何通过`ClassPathXmlApplicationContext`来启动和初始化Bean...

    Spring的IoC容器初始化源码解析

    ### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...

    一 基于 注解 的方式 初始化 spring 容器

    这就是基于注解的Spring初始化和依赖注入的基本原理,它极大地简化了代码,提高了可维护性,并且使得应用更易于测试。 总结一下,基于注解的Spring初始化主要涉及以下几点: 1. 使用`@Component`注解标记希望由...

    Spring Bean的初始化和销毁实例详解

    Spring Bean的初始化和销毁实例详解 Spring Bean的初始化和销毁是Spring框架中一个非常重要的概念,它们都是Bean生命周期中不可或缺的一部分。在Spring框架中,我们可以使用多种方式来控制Bean的初始化和销毁,以下...

    spring配置实例化后执行的初始化方法比对

    spring配置对象实例化后执行的方法,两种实现比对,通过InitializingBean接口,并实现arterPropertiesSet()方法;或者通过applicationContext.xml配置init-method属性

    浅谈spring容器中bean的初始化

    在Spring框架中,Bean的初始化是一个关键的概念,它涉及到Bean的生命周期管理以及Spring容器如何创建、配置和管理这些Bean。本文将深入探讨Spring容器中Bean的初始化过程。 首先,Spring容器根据XML配置文件(如`...

    初始化后可访问Spring管理的Bean

    初始化后可访问Spring管理的Bean

    Spring MVC启动时初始化的几个常用方法

    在Spring MVC框架中,应用程序启动时会执行一系列初始化操作,这些操作对于理解Spring MVC的工作原理至关重要。本篇文章将深入探讨Spring MVC启动时初始化的几个常用方法,并解释它们在实际开发中的作用。 首先,...

    spring-startup

    三、Spring初始化过程 1. 创建Bean实例:根据Bean定义,Spring会创建Bean实例。如果配置了单例(singleton),那么Spring会缓存该Bean,后续请求将直接返回同一实例。 2. 属性注入:Spring会根据Bean定义中的属性...

    从Dubbo启动看Dubbo和Spring的关系1

    这是一个重要的扩展点,因为Dubbo的一些组件,如`DubboConfigBean`,实际上就是`BeanFactoryPostProcessor`的实现,它会在Spring初始化完成后,进一步处理Dubbo相关的配置信息,比如服务提供者、消费者等信息的解析...

Global site tag (gtag.js) - Google Analytics