SSM的加载顺序


一直采用的是Tomcat,所以这里也以Tomcat加载SSM项目时配置文件的处理顺序作为例子.....

Tomcat加载顺序

Tomcat启动后,首先会先加载你项目下的web.xml,ssm在项目运行时,首先会加载web.xml,然后按序寻找如下的节点:

  1. context-param
  2. listener
  3. filter
  4. servlet
  5. interceptor

如下,是我从Tomcat的一次启动过程中按日志打印顺序截取出来的信息

信息: Initializing Spring root WebApplicationContext
信息: Initializing log4j from [classpath:log4j.properties]
信息: Initializing Spring FrameworkServlet 'spring-dispatcher'

而我的web.xml如下,首先是context-param:

<!--指定Spring配置-->
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml</param-value>
</context-param>

<!--指定log4j配置-->
<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
		<param-name>log4jRefreshInterval</param-name>
		<param-value>600000</param-value>
</context-param>

接着是,监听器


	<!-- Spring 容器加载 -->
	 <listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>

然后再是过滤器

<!--解决中文乱码问题 -->
<filter>
	   <filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
</filter>
<filter-mapping
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
</filter-mapping>

最后是servlet和拦截器,SpringMVC其实是对servlet的封装来着,如果用过原生的servlet,我们都知道它需要在web配置好多的servlet和servlet-mapping节点。而通过<load-on-startup>节点,我们可以指定Tomcat启动时初始化servlet的优先级,至于拦截器,其实本质上也是一个servlet来着~如登录判读,缓存判断.

	<!-- SpringMVC的前端控制器 -->
	<servlet>
		<servlet-name>spring-dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		
		<!-- 加载配置文件路径 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<!-- 何时启动 大于0的值表示容器启动时初始化此servlet,正值越小优先级越高 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- Spring MVC配置文件结束 -->

	<!-- SpringMVC拦截设置 -->
	
	<servlet-mapping>
		<servlet-name>spring-dispatcher</servlet-name>
		<!-- 由SpringMVC拦截所有请求 -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<!-- SpringMVC拦截设置结束 -->
	

在这里插入图片描述


Spring加载顺序

Spring在初始化容器时,会先解析和加载所有的Bean (如果没有设置为延迟加载的话,即bean标签中的lazy-init没有设置为true),如果符合要求则通过Class生成BeanDefinition,存入BeanFactory中,在加载完所有Bean Class后,开始有序的通过BeanDefinition实例化Bean。同一级别的bean一般按照文件中的顺序进行初始化。

补充两点点,(1)如果一个bean的scope属性为scope="pototype"多例时,lazy-init的属性值即使设置为false,容器启动时也不会实例化bean,而是等到需要时,再进行实例化。(2)如果一个beanA依赖于另一个beanB,而你需要将beanA设置为单例,beanB设置为多例时,不能简单的将将beanB嵌套在beanA中,因为那样设置的话,由于外围的beanA在启动的时候就已经设置为单例了,而beanA又依赖于beanB,所以连带着beanB也被实例化,此时会将beanB也实例化为单例的。如下图所示:

在这里插入图片描述
在这里插入图片描述
地址都一样的:
在这里插入图片描述
解决方法时不用注入的方式,并将外围bean实现BeanFactoryAware 接口,如下:

public class TestBeans implements BeanFactoryAware {
    private TestSingleton tool;
    private BeanFactory factory;
    public TestBeans(){
        System.out.println("单例初始化");
    }

    public TestSingleton getTool() {
        return tool;
    }
    public void init(){
        System.out.println("多例初始化");
        this.tool = (TestSingleton) factory.getBean("tool");
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        factory = beanFactory;
    }
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

legendaryhaha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值