`
yourenyouyu2008
  • 浏览: 281989 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring代码分析一:加载与初始化

 
阅读更多

 

转载地址:http://www.cnblogs.com/bobzeng/articles/1877140.html

一般的Web项目都会在web.xml中加入Spring监听器,内容如下:

1
2
3
4
5
6
7
8
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext-struts.xml,classpath*:spring/applicationContext.xml</param-value>
</context-param>

我们的问题是,Spring是何时以及如何加载我们的配置文件来初始化Bean工厂的,带着这些问题,我们展开研究:

我们先来看看web.xml中配置的监听器的类,来回答我们的问题,Spring是何时来加载我们的配置文件的:

org.springframework.web.context.ContextLoaderListener

image

它继承了javax.servlet.ServletContextListener接口。

ServletContextListener是J2EE Servlet API中的一个标准接口,

它能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。

当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener来处理。

 

这里面有两个方法我们比较感兴趣:

1
2
3
4
5
6
7
/**
 * Create the ContextLoader to use. Can be overridden in subclasses.
 * @return the new ContextLoader
 */
protected ContextLoader createContextLoader() {
      return new ContextLoader();
}

这个方法构造一个默认的ContextLoader,ContextLoader可以理解为Spring上下文的加载器。之所以这样去定义这样一个类,是为了开发人员进行重写此方法来使用一个自定义的Spring上下文的加载器。

1
2
3
4
5
6
7
/**
 * Initialize the root web application context.
 */
public void contextInitialized(ServletContextEvent event) {
     this.contextLoader = createContextLoader();
     this.contextLoader.initWebApplicationContext(event.getServletContext());
}

这个方法很简单,仅仅只是调用了createContextLoader()构造了ContextLoader,并调用其初始化方法。

由此,我们可以得出结论,Spring是在Web项目启动时,通过ServletContextListener机制,来加载以及初始化Spring上下文的。

 

下面,我们好好研究一下Spring是如何加载其上下文的:

我们先定位ContextLoader类。

image

看看此类的initWebApplicationContext()方法(省略了不重要的语句)

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
/**
 * Initialize Spring's web application context for the given servlet context,
 * according to the "{@link #CONTEXT_CLASS_PARAM contextClass}" and
 * "{@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params.
 * @param servletContext current servlet context
 * @return the new WebApplicationContext
 * @throws IllegalStateException if there is already a root application context present
 * @throws BeansException if the context failed to initialize
 * @see #CONTEXT_CLASS_PARAM
 * @see #CONFIG_LOCATION_PARAM
 */
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
        throws IllegalStateException, BeansException {
    if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
            throw new IllegalStateException(
                    "Cannot initialize context because there is already a root application context present - " +
                    "check whether you have multiple ContextLoader* definitions in your web.xml!");
    }
    try {
        // Determine parent for root web application context, if any.
        ApplicationContext parent = loadParentContext(servletContext);
 
        // Store context in local instance variable, to guarantee that
        // it is available on ServletContext shutdown.
        this.context = createWebApplicationContext(servletContext, parent);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,this.context);
        currentContextPerThread.put(Thread.currentThread().getContextClassLoader(),this.context);
 
        return this.context;
    }catch (RuntimeException ex) {
        logger.error("Context initialization failed", ex);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
        throw ex;
    }catch (Error err) {
        logger.error("Context initialization failed", err);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
        throw err;
    }
}

其中的有两句比较重要,我们来看看:

ApplicationContext parent = loadParentContext(servletContext);

这个方法的用途主要是用来解决Spring共享环境的,即,如果我们有多个WAR包部署在同一个服务器上,而且这些WAR都共享某一套业务逻辑层。如何共享一套业务逻辑包配置而不要每个WAR都单独配置,这时我们就可能需要Spring的共享环境了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected ApplicationContext loadParentContext(ServletContext servletContext) throws BeansException {
    ApplicationContext parentContext = null;
    // 从web.xml中读取父工厂的配置文件,默认为:"classpath*:beanRefContext.xml"
    String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
 
    // 从web.xml中读取父类工厂的名称
    String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
 
    if (parentContextKey != null) {
        // locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"
        BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
        this.parentContextRef = locator.useBeanFactory(parentContextKey);
        parentContext = (ApplicationContext) this.parentContextRef.getFactory();
    }
 
    return parentContext;
}

现在我们引入BeanFactoryLocator,它是Spring配置文件的一个定位器,Spring官方给它的定义是用来查找,使用和释放一个BeanFactory或其子类的接口。下面我们看看此图:

image

ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);

是根据参数locatorFactorySelector去一个单例工厂中去拿一个对应的BeanFactoryLocator,也即,如果工厂中没有对 应于locatorFactorySelector的BeanFactoryLocator对象,那就返回一个新的BeanFactoryLocator 实例(这里是ContextSingletonBeanFactoryLocator的实例),否则,就从工厂里取现有的 BeanFactoryLocator对象。

ContextSingletonBeanFactoryLocator里维护了一个静态的Map对象instances,每次需要新增 BeanFactoryLocator实例时都会更新这个Map对象,这个Map对象是以配置文件名为KEY,BeanFactoryLocator对象 为值。原因很简单,就是希望同一个配置文件只被初始化一次。

如果没有在web.xml中定义locatorFactorySelector这个参数,父环境的配置文件默认使用:"classpath*:beanRefContext.xml"

 

this.parentContextRef = locator.useBeanFactory(parentContextKey);

此方法定义在SingletonBeanFactoryLocator类中,同样是一个单例工厂模式,判断传入的参数parentContextKey对 应的BeanFactory是否有被初始化,经过上面的 ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector)指定 Spring父环境配置文件,这个方法判断指定的父环境是否被初始化,如果有则返回,没有就进行初始化。看看此方法的实现:

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
40
41
42
43
44
45
46
47
48
49
public BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException {
    synchronized (this.bfgInstancesByKey) {
        BeanFactoryGroup bfg = (BeanFactoryGroup) this.bfgInstancesByKey.get(this.resourceLocation);
 
        if (bfg != null) {
            bfg.refCount++;
        }else {
            // Create the BeanFactory but don't initialize it.
            BeanFactory groupContext = createDefinition(this.resourceLocation, factoryKey);
 
            // Record its existence now, before instantiating any singletons.
            bfg = new BeanFactoryGroup();
            bfg.definition = groupContext;
            bfg.refCount = 1;
            this.bfgInstancesByKey.put(this.resourceLocation, bfg);
            this.bfgInstancesByObj.put(groupContext, bfg);
 
            // Now initialize the BeanFactory. This may cause a re-entrant invocation
            // of this method, but since we've already added the BeanFactory to our
            // mappings, the next time it will be found and simply have its
            // reference count incremented.
            try {
                initializeDefinition(groupContext);
            }catch (BeansException ex) {
                this.bfgInstancesByKey.remove(this.resourceLocation);
                this.bfgInstancesByObj.remove(groupContext);
                throw new BootstrapException("Unable to initialize group definition. " +
                    "Group resource name [" +this.resourceLocation + "], factory key [" + factoryKey + "]", ex);
            }
        }
 
        try {
            BeanFactory beanFactory = null;
            if (factoryKey != null) {
                beanFactory = (BeanFactory) bfg.definition.getBean(factoryKey, BeanFactory.class);
            }else if (bfg.definitioninstanceof ListableBeanFactory) {
                beanFactory = (BeanFactory) BeanFactoryUtils.beanOfType((ListableBeanFactory) bfg.definition, BeanFactory.class);
            }else {
                throw new IllegalStateException(
                    "Factory key is null, and underlying factory is not a ListableBeanFactory: " + bfg.definition);
            }
            return new CountingBeanFactoryReference(beanFactory, bfg.definition);
         }catch (BeansException ex) {
             throw new BootstrapException("Unable to return specified BeanFactory instance: factory key [" +
                    factoryKey + "], from group with resource name [" +this.resourceLocation + "]", ex);
         }
 
    }
}

此方法分为两作了两件事,

第一,初始化上下文,主意这里初始化的是从web.xml配置参数里的Spring配置文件,也是上面讲loadParentContext方法里的

BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);

这句指定的参数。这里初始化的是这个配置文件所有Bean。我们指定的factoryKey对应的Bean也是其中之一。

 

第二,从已经初始化的Spring上下文环境中获取Spring父环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans
     <bean id="factoryBeanId" class="org.springframework.context.support.ClassPathXmlApplicationContext"
         <constructor-arg
                <list
                     <value>sharebean.xml</value
                </list
         </constructor-arg
     </bean>
     <bean id="factoryBeanId2" class="org.springframework.context.support.ClassPathXmlApplicationContext"
         <constructor-arg
                <list
                     <value>sharebean2.xml</value
                </list
         </constructor-arg
     </bean>
</beans>
1
2
3
4
5
6
7
8
9
10
<!—========================= web.xml ========================= --> 
<context-param
        <param-name>locatorFactorySelector</param-name
        <param-value>beanRefFactory.xml</param-value
</context-param
 
<context-param
        <param-name>parentContextKey</param-name
        <param-value>factoryBeanId</param-value
</context-param>

这个一个典型的构造父环境的配置,web项目在启动的时候就会发现里面有Spring父环境的配置,那么Spring首先就会生成一个对应的配置文件为 beanRefFactory.xml的BeanFactory(web.xml中的locatorFactorySelector参数指定),同时 Spring在解析的时候,会发现factoryBeanId的配置同样为BeanFacotry(beanRefFactory.xml中 factoryBeanId对应的Bean),所以Spring在拿父环境时就会写成:

beanFactory = (BeanFactory) bfg.definition.getBean(factoryKey, BeanFactory.class);

 

方法实现里引入了BeanFactoryGroup类。类的结构很简单

image

refCount:用来记录实例被外部引用的记数,当调用locator.useBeanFactory(parentContextKey)方法时,引 用数就会加1,当调用CountingBeanFactoryReference#release方法时,引用数就会减1,当它变成0时,Spring就 会释放掉它占用的内存,同时也会销毁掉它definition变量引用的BeanFactory。下次再调用 locator.useBeanFactory(parentContextKey)就会重新初始化BeanFactory。说到release,请同学 们参考ContextLoader中如下的两条语句:

// 在调用CountingBeanFactoryReference#release后,即使对象已经销毁,这个Map仍然可以返回locator对象。

BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);

// 如果对象已经销毁,再调用此方法会再一次初始化BeanFactory 
this.parentContextRef = locator.useBeanFactory(parentContextKey);

 

bfgInstancesByKey:一个Map对象,以配置文件名为Key,配置文件解析后生成的BeanFactory构成的BeanFactoryGroup为值。

bfgInstancesByObj:一个Map对象,以BeanFactoryGroup.definitiion为Key,以 BeanFactoryGroup为值。这个对象主要还是在CountingBeanFactoryReference#release时使用。

 

 

下面,我看再看看另一个地方:

1
2
3
4
5
6
7
if (parentContextKey != null) {
      // locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"
      BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
      this.parentContextRef = locator.useBeanFactory(parentContextKey);
      parentContext = (ApplicationContext) this.parentContextRef.getFactory();
}
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);

上面这句仅仅是做了如下工作:

1
2
3
4
5
6
BeanFactoryLocator bfl = (BeanFactoryLocator) instances.get(resourceLocation);
if (bfl == null) {
       // 仅仅只是设置了ContextSingletonBeanFactoryLocator里的resourceLocation属性的值,并没有初始化工厂。
        bfl = new ContextSingletonBeanFactoryLocator(resourceLocation);
       instances.put(resourceLocation, bfl);
}

而我们使用工厂模式的时候,一般是把对象初始化好了,再给外部使用,为什么Spring这里要多此一举,在调用getInstance这后还要去调用useBeanFactory来初始化父环境?为什么Spring开发者不写成如下:

1
2
3
4
5
6
7
BeanFactoryLocator bfl = (BeanFactoryLocator) instances.get(resourceLocation);
if (bfl == null) {
        bfl = new ContextSingletonBeanFactoryLocator(resourceLocation);
        // 下面这句可能换成 initBeanFactory 类似语句,这里只是打个比方
         bfl.useBeanFactory(parentContextKey);
        instances.put(resourceLocation, bfl);
}

本来我认为这个写法是必须的,后来想想也不是,不过这里体现了Spring的灵活设计。如果按排上面的方法进行改造有几点不妥,1,每次都会初始化,开销 比较大,可能有需求是需要延迟初始化的。2,每次都需要初始化都需要传入两个参数,分别为:配置文件名与父工厂名,3,类职责混乱,比如一个配置文件中可 能定义了多个父环境的Bean,采用Spring这种方法是很清晰的:

1
2
3
4
// 返回BeanFactoryLocator方便定位某个配置文件。
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(“classpath*: parentBeanFactory.xml”);
parentContextRef1 = locator.useBeanFactory("parent1Key");
parentContextRef2 = locator.useBeanFactory("parent2Key");

而使用我们改造的方法,则要写成如下:

1
2
parentContextRef1 = ContextSingletonBeanFactoryLocator.getInstance("parentBeanFactory.xml","parent1Key");
parentContextRef2 = ContextSingletonBeanFactoryLocator.getInstance("parentBeanFactory.xml","parent2Key");

相当麻烦且无语,引用了也只是这个配置文件中的某一个Bean的引用,没什么意义。

这就是为什么BeanFactoryLocator接口存在的一个原因,用于查找某个配置文件中的一个BeanFactory。

1
2
3
public interface BeanFactoryLocator {
        BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException;
}

this.context = createWebApplicationContext(servletContext, parent);

我们来看看这个函数做了些什么:

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
40
41
42
43
44
45
46
47
48
protected WebApplicationContext createWebApplicationContext(
            ServletContext servletContext, ApplicationContext parent) throws BeansException {
       // 获得需要实例化的CONTEXT类名,确定ContextClass的类型。如果在web.xml中配置了contextClass这个parameter,
        // 使用这个指定的类作为ContextClass,会抛出ClassNotFound的异常。反之,使用默认的XmlWebApplicationContext
        Class contextClass = determineContextClass(servletContext);
 
        // 所有的WebApplicationContext必须实现ConfigurableWebApplicationContext接口
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
            throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
                    "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
        }
 
        ConfigurableWebApplicationContext wac =
                (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
 
       // 设置父环境
        wac.setParent(parent);
       // 设置Servlet上下文环境
        wac.setServletContext(servletContext);
       // 设置Spring配置文件路径
        wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
       customizeContext(servletContext, wac);
       wac.refresh();
 
       return wac;
}
 
protected Class determineContextClass(ServletContext servletContext) throws ApplicationContextException {
       // 获得需要实例化的CONTEXT类名,在web.xml中有设置,如果没有设置,那么为空
        String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
       if (contextClassName != null) {
           try {
                return ClassUtils.forName(contextClassName);
            }catch (ClassNotFoundException ex) {
                throw new ApplicationContextException("Failed to load custom context class.", ex);
            }
       }else {
 
           //如果在spring web.xml中没有设置context类位置,那么取得默认context
           //取得defaultStrategies配置文件中的WebApplicationContext属性 
            contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
           try {
                return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
           }catch (ClassNotFoundException ex) {
                throw new ApplicationContextException("Failed to load default context class.", ex);
           }
       }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
 
static {
     // Load default strategy implementations from properties file.
     // This is currently strictly internal and not meant to be customized
     // by application developers.
     try {
         ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
         defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
     }catch (IOException ex) {
         throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
     }
}

// 在ContextLoader.properties里定义如下

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

再来看看Spring是如果进行初始化ApplicationContext的。就以XmlWebApplicationContext来说,它继承了 ConfigurableWebApplicationContext这个接口,里面有个refresh()方法,我们可以看看它的实现 (AbstractApplicationContext):

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
40
41
42
43
44
45
46
47
48
49
50
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) {
                // Destroy already created singletons to avoid dangling resources.
                beanFactory.destroySingletons();
 
                // Reset 'active' flag.
                cancelRefresh(ex);
 
                // Propagate exception to caller.
                throw ex;
            }
        }
}

这个方法的实现由于涉及的东西比较多,比较国际化,事件等等,等我们理解了后续的源代码分析之后再重新过来进行研究。这样效率更高点。

这样关于Spring在web项目中加载及初始化的方式我们大概也了解的比较清楚了,我们可以看到,Spring就第一步,加载都已经做了很多工作,不得不佩服Spring团队的智慧。

 

最后,Spring加载完成之前,会将ApplicationContext放入ServletContext中,方便程序进行访问。

1
2
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,this.context);
currentContextPerThread.put(Thread.currentThread().getContextClassLoader(),this.context);

其中WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE定义如下:

String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

 

Spring环境

加载组件:ContextLoaderListener

配置路径:Servlet环境初始化参数contextConfigLocation指定的路径

缺省路径: 没有缺省路径

 

Spring环境的父环境

加载组件:ContextLoaderListener和ContextSingletonBeanFactoryLocator

配置路径:Servlet环境初始化参数locatorFactorySelector指定Bean工厂定位器使用的给BeanFactory,Servlet环境初始化参数parentContextKey指定Bean工厂定位器用于查找BeanFactory的关键字

缺省路径: parentContextKey的缺省路径是classpath*:beanRefFactory.xml

 

这里我们还有一个功能相近的类没有进行说明:

ContextJndiBeanFactoryLocator

分享到:
评论

相关推荐

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

    Spring的IoC容器初始化源码解析,包括资源定位、加载、注册3个过程

    深入解析Spring IoC:源码与实践指南

    这包括从AnnotationConfigApplicationContext的实例化开始,到DefaultListableBeanFactory工厂的建立,再到AnnotatedBeanDefinitionReader的初始化,这一系列过程共同构成了Spring容器的加载核心。同时,本文还探讨...

    Spring bean 动态注册,jar包热替换

    Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class...测试示例中是spring boot 的部分代码,动态加载的内容为接口实现类,且初始化时加载本地的实现类,动态加载后改为非程序加载目录中的jar实现类。

    spring源代码解析

    对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用 ...

    在Spring Boot中加载初始化数据的实现

    主要介绍了在Spring Boot中加载初始化数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    让spring解决控制springboot中bean的加载顺序的问题.docx

    只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器。 而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间件需要完成...

    Spring.html

    --全局初始化参数--&gt; &lt;context-param&gt; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt; &lt;param-value&gt;classpath:applicationContext.xml&lt;/param-value&gt; 4.在Servlet中使用WebApplicationContextUtils获取容器...

    Spring:Rails应用程序预加载器

    更改配置/初始化程序/ gem依赖项时重新启动应用程序 兼容性 Ruby版本:MRI 2.5,MRI 2.6 Rails版本:5.2、6.0(当您进行rails new生成应用程序时,默认情况下会安装Spring) Spring广泛使用Process.fork ,因此将...

    spring:spring源码级别的学习

    2、IOC初始化 声明一个IOC容器,Map 3、scan-package 配置一个包路径,扫描到相关的类 4、实例化 将扫描到的相关类,利用反射机制实例化,并且保存到IOC容器之中 5、依赖注入 (DI)自动给IOC容器中的对象,需要自动...

    spring boot源码

    spring boot源代码,通过源代码可以了解spring boot底层运行机制。 1. 初始化各种属性,加载成对象  读取环境属性(Environment)  系统配置(spring.factories)  参数(Arguments、application.properties)...

    spring2.5.6源码

    源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的,但当你能够看明白的时候,相信快乐也会随之而来,为了减少痛苦,更快的带来快乐,在这里希望通过这篇文章对觉得困难的朋友有一个帮助。 本文以...

    23-Listener-源代码.rar

    案例-使用监听器完成定时生日祝福、,一、监听器Listener 二、邮箱服务器。 1.什么是监听器? 2.监听器有哪些?...b、加载一些初始化的配置文件 --- spring的配置文件 c、任务调度----定时器----Timer/TimerTask

    吴天雄--Spring笔记.doc

    第一天内容:Spring框架简介(EJB、JMX、Spring核心功能、Spring模块详解、Spring重要概念(容器)、Spring容器初始化的整个流程、Spring后处理器),IOC详解,Spring环境搭建,Spring创建Bean的三种方式,scope属性...

    java相关的2024面试题集锦

    SpringBoot特性以及它与Spring、SpringMVC的区别 Jvm类加载机制 Java中的锁机制 Java按行读取txt中的内容 - 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、解析和初始化,最终形成可以被虚拟机...

    Springboot项目启动时加载数据库数据到内存.rar

    博客地址:https://blog.csdn.net/fukaiit/article/details/92853086 1. 启动后访问http://localhost:8848/code,可见... 2. 新建一个只有key和value两个字段的表code 3. 不要轻易浪费积分下载代码,没什么实质内容

    SpringBoot (4.71G)精华详解

    1.Spring核心讲解与内容详述.mp4;`-{0B:r2E;]$u+m 2.Spring源码环境搭建与执行流程解析.mp4/j1};W;...14.Spring单例Bean的初始化与缓存流程详解.mp4%U7X2[;{3z 15.Spring对象属性赋值与作用域源码解

    Spring.net框架

    本部分代码仅仅提供一种功能演示,如果实际应用仍需进一步完善(建议使用一些成型的Ioc框架,例如Spring.net或Castle等)。经过改造后 的系统,组件间依赖关系如下图: 可以看出这次实现了真正的“针对接口编程”...

    Spring中文帮助文档

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring API

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring面试题

    在web应用启动时就会加载初始化ActionServlet,ActionServlet从 struts-config.xml文件中读取配置信息,把它们存放到各种配置对象 当ActionServlet接收到一个客户请求时,将执行如下流程. -(1)检索和用户请求匹配的...

Global site tag (gtag.js) - Google Analytics