通过tomcat容器启动spring容器的启动过程

56 篇文章 2 订阅
订阅专栏
49 篇文章 1 订阅
订阅专栏

参考网站:https://www.cnblogs.com/RunForLove/p/5688731.html

通过对spring源码的解读,跟踪spring容器的启动过程,掌握SpringMVC是如何工作的;掌握Spring源码的设计和增强阅读源码的技巧。为可持续性的使用spring框架高效集成开发,解决系统一些疑难杂症提供强有力的支撑。

一、需要掌握的理论业务点:

1、Web容器初始化过程

2、Spring MVC 在web.xml中的配置

3、理解ServletContextListener

4、掌握理解ContextLoadListener

5、DispatcherServlet初始化(HttpServletBean • FrameworkServlet • DispatcherServlet)

6、ContextLoadListener与DispatcherServlet的关系

7、DispatcherServlet的设计

8、DispatcherServlet工作原理

二、分析各个理论节点的知识

1、要想了解spring容器在web容器中启动的过程,首先我们需要知道web容器在tomcat中的生命周期,方可理解spring容器是如何在web容器中启动、运行、以及销毁、的生命周期

上图展示了web容器在启动过程中主要业务走向,其官方给出的解释是:

When a web application is deployed into a container, the following steps must be performed, in this order, before the web application begins processing client requests.
1、Instantiate an instance of each event listener identified by a <listener> element in the deployment descriptor.
2、For instantiated listener instances that implement ServletContextListener, call the contextInitialized() method.
3、Instantiate an instance of each filter identified by a <filter> element in the deployment descriptor and call each filter instance's init() method.
4、Instantiate an instance of each servlet identified by a <servlet> element that includes a <load-on-startup> element in the order defined by the load-on-startup element values, and call each servlet instance's init() method.

翻译是:

web应用程序部署到容器中时,必须按照以下顺序在web应用程序开始处理客户机请求之前执行以下步骤。

实例化由部署描述符中的元素标识的每个事件侦听器的实例。

对于实现ServletContextListener的实例化侦听器实例,调用contextInitialized()方法。

实例化由部署描述符中的元素标识的每个过滤器的实例,并调用每个过滤器实例的init()方法。

实例化由元素标识的每个servlet的实例,该元素按加载启动元素值定义的顺序包含元素,并调用每个servlet实例的init()方法。

大致的意思是,tomcat在启动web容器的时候会启动一个叫ServletContextListener的监听器,每当在web容器中有ServletContextListener这个接口被实例化的时候,web容器会通知ServletContextListener被实例的对象去执行其contextInitialized()的方法进行相应的业务处理,而spring框架在设计的过程中ContextLoadListener这个类实现了ServletContextListener这个接口,因此每当有ContextLoadListener这个类被实例化的时候,web容器会通知他执行contextInitialized()这个方法

2、spring MVC在web.xml在的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<display-name>app</display-name>

	<!-- 加载Spring配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-starter.xml</param-value>
	</context-param>

	<!-- Spring监听器 -->
	<listener>
		<description>Spring监听器</description>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

 在web.xm配置中由<context-param>将spring的配置文件引入加载到web容器中,

<listener>配置项是在web容器中启用监听,其所配置的class是需要启用的监听器,因此spring容器的启用是同过org.springframework.web.context.ContextLoaderListener进行spring容器的启动,而ContextLoaderListener监听实现的是ServlectContextListener接口,因此在其实例化的过程中,contextInitialized()会被调用,从而进行spring容器的启动与创建的过程中

ContextLoaderListener中的contextInitialized()进行了spring容器的启动配置并且刷新实例化整个SpringApplicationContext中的Bean。因此,如果我们的Bean配置出错的话,在容器启动的时候,会抛异常出来的。

@Override
public void contextInitialized(ServletContextEvent event) {
    initWebApplicationContext(event.getServletContext());
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    //Spring 启动的句柄,spring容器开始启动的根目录
    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!");
    } else {
        Log logger = LogFactory.getLog(ContextLoader.class);
        servletContext.log("Initializing Spring root WebApplicationContext");
        if(logger.isInfoEnabled()) {
            logger.info("Root WebApplicationContext: initialization started");
        }

        long startTime = System.currentTimeMillis();

        try {
            //处理spring容器是否已经创建(只创建没有创建spring的各个bean)
            if(this.context == null) {
                this.context = this.createWebApplicationContext(servletContext);
            }

            if(this.context instanceof ConfigurableWebApplicationContext) {
                ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
                if(!cwac.isActive()) {
                    if(cwac.getParent() == null) {
                        ApplicationContext parent = this.loadParentContext(servletContext);
                        cwac.setParent(parent);
                    }

                    //Spring容器创建完成后,加载spring容器的各个组件
                    this.configureAndRefreshWebApplicationContext(cwac, servletContext);
                }
            }

            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
            ClassLoader ccl = Thread.currentThread().getContextClassLoader();
            if(ccl == ContextLoader.class.getClassLoader()) {
                currentContext = this.context;
            } else if(ccl != null) {
                currentContextPerThread.put(ccl, this.context);
            }

            if(logger.isDebugEnabled()) {
                logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
            }

            if(logger.isInfoEnabled()) {
                long elapsedTime = System.currentTimeMillis() - startTime;
                logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
            }

            return this.context;
        } catch (RuntimeException var8) {
            logger.error("Context initialization failed", var8);
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var8);
            throw var8;
        } catch (Error var9) {
            logger.error("Context initialization failed", var9);
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var9);
            throw var9;
        }
    }
}

以上完成Spring容器的创建 ,并在代码中配置加载Spring容器启动的配置文件,以及调用Spring容器的加载入口

this.configureAndRefreshWebApplicationContext(cwac, servletContext);

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
    String configLocationParam;
    if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
        configLocationParam = sc.getInitParameter("contextId");
        if(configLocationParam != null) {
            wac.setId(configLocationParam);
        } else {
            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
        }
    }

    wac.setServletContext(sc);
    //设置Spring容器启动的起始配置文件
    configLocationParam = sc.getInitParameter("contextConfigLocation");
    if(configLocationParam != null) {
        wac.setConfigLocation(configLocationParam);
    }

    ConfigurableEnvironment env = wac.getEnvironment();
    if(env instanceof ConfigurableWebEnvironment) {
        ((ConfigurableWebEnvironment)env).initPropertySources(sc, (ServletConfig)null);
    }

    this.customizeContext(sc, wac);
    //初始化spring的各个组件,以及spring容器中的各个bean
    wac.refresh();
}
Spring容器加载bean的过程入口:wac.refresh();
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
    String configLocationParam;
    if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
        configLocationParam = sc.getInitParameter("contextId");
        if(configLocationParam != null) {
            wac.setId(configLocationParam);
        } else {
            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
        }
    }

    wac.setServletContext(sc);
    //设置Spring容器启动的起始配置文件
    configLocationParam = sc.getInitParameter("contextConfigLocation");
    if(configLocationParam != null) {
        wac.setConfigLocation(configLocationParam);
    }

    ConfigurableEnvironment env = wac.getEnvironment();
    if(env instanceof ConfigurableWebEnvironment) {
        ((ConfigurableWebEnvironment)env).initPropertySources(sc, (ServletConfig)null);
    }

    this.customizeContext(sc, wac);
    //初始化spring的各个组件,以及spring容器中的各个bean
    wac.refresh();
}

加spring容器中bean

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList();
    List<String> orderedPostProcessorNames = new ArrayList();
    List<String> nonOrderedPostProcessorNames = new ArrayList();
    String[] var8 = postProcessorNames;
    int var9 = postProcessorNames.length;

    String ppName;
    BeanPostProcessor pp;
    for(int var10 = 0; var10 < var9; ++var10) {
        ppName = var8[var10];
        if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if(pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        } else if(beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        } else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
    Iterator var14 = orderedPostProcessorNames.iterator();

    while(var14.hasNext()) {
        String ppName = (String)var14.next();
        BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if(pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }

    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
    //存放spring容器中加载的各个bean
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
    Iterator var17 = nonOrderedPostProcessorNames.iterator();

    while(var17.hasNext()) {
        ppName = (String)var17.next();
        pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if(pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }

    registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

通过SerlvetContextListener这一特性还可以做其它的运用,如缓存数据在服务启动过程中的初始化

https://blog.csdn.net/qq_31854907/article/details/86304955

 

 

 

 

 

 

Spring Cloud (8) | Spring Boot项目改造成tomcat容器启动
Web3 & Basketball
12-26 2948
spring cloud项目在本地很容易用main方法启动,但是发不到测试和生产服务器上,很多童鞋还是习惯使用tomcat容器启动,并查看log,OK,让我们来讲述如何来做: Step 1: 在pom文件里排除spring boot tomcat 依赖: <dependency> <groupId>org.springframework.boot</groupId
看了就会:多线程下载图片并压缩,多线程下载能提高效率吗?
mf97532的博客
06-23 300
前言 需求 导出Excel:本身以为是一个简单得导出,但是每行得记录文件中有一列为图片url,需要下载所有记录行对应得图片,然后压缩整个文件夹。 这里只做4.5.得代码讲解描述,其它也没什么好说得,话不多说上代码. 实现思路 多线程实现使用了线程池,Jdk1.8并发包下的CompletableFuture 第一步:得到基础数值 // 线程数 Integer threadNum = 10; // 每条线程需要处理的图片数 int d
Spring Boot中Tomcat是怎么启动
十指波课堂的博客
09-04 240
Spring Boot一个非常突出的优点就是不需要我们额外再部署Servlet容器,它内置了多种容器的支持。我们可以通过配置来指定我们需要的容器。本文以我们平时最常使用的容器Tomcat为列来介绍以下两个知识点:Spring Boot是怎么整合启动Tomcat容器的;在Spring Boot中,怎么进行Tomcat的深度配置。Spring Boot整合启动Tomcat的流程#对于看源代码,每个人都...
SPI(SerialPeripheralinterface)------串行外设接口
最新发布
MaxCyclotron的博客
08-28 1562
SPI简要介绍
Tomcat是如何启动Spring项目的?
m0_67391521的博客
08-26 2037
tomcat启动ServletContext容器的时候会发布ServletContextEvent事件。Spring就通过实现ServletContextListener接口,监听该事件来监听ServletContext的生命周期。
tomcat+spring启动顺序
xmind果果
11-10 7196
原文地址:https://www.2cto.com/kf/201701/583009.html 一.使用spring等框架的web程序在Tomcat下的启动流程1)Tomcat是根据web.xml来启动的。首先到web.xml2)web.xml中负责启动springspring mvc。对应的启动配置文件分别是启动spring mvc,并进行所有资源路径映射 <servlet> <servlet
Tomcat启动过程分析(下)
hanekawa的博客
08-10 3195
如何将连接放入容器 connector.getContainer()得到的容器应该是StandardEngine,StandardEngine没有invoke方法,它继承于ContainerBase,ContainerBase的invoke方法是传递到Pipeline,调用了Pipeline的invoke方法。Pipeline是一个管道类,每一个管道类Pipeline包含数个阀类,阀类是实现了V
springboot 基于Tomcat容器的自启动流程分析
08-25
Spring Boot 中,Tomcat 容器的自启动流程是通过自动装配实现的。在 spring-boot-autoconfigure-2.0.6.RELEASE.jar 中,我们可以找到两个自动装配类,分别包含了三个定制器(面向对象的单一职责原则),还有一个...
启动Spring项目详细过程(小结)
08-25
通过本文,我们了解了启动Spring项目的详细过程,该过程包括将项目放到web项目容器中、容器启动时加载读取web.xml配置文件、ContextLoaderListener中的contextInitialized()方法、初始化spring容器四个步骤。...
Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解
08-30
Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解 Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解是Spring Boot启动过程的重要组件之一,本文将详细介绍Springboot内嵌...
jvm实例,tomcat容器spring容器,在内存中的关系和tomcat的类加载机制
qq_22162093的博客
04-03 1099
jvm实例,tomcat容器spring容器,在内存中的关系 问题: 1.一个java项目对应一个jvm 吗? 2.tomcat里面加载多个java项目 ,是不是用了一个jvm? 3.java项目中的spring容器,部署到tomcat容器启动tomcat以后的jvm实例 ,在内存中是怎么一个包含关系? 1、集群环境可能是多个jvm 2、一个java进程就是一个jvm,main方法启动的,而同一个tomcat的多个web应用都在一个jvm里 3、jvm包含tomcat运行环境,tomcat加载了应用上
启动Spring容器的方法
wsfengye的博客
02-02 133
一、在web.xml中配置Spring容器启动 (通用的方法)              &lt;context-param&gt;     &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;      &lt;param-value&gt;/WEB-INF/classes/applicationContext.xml&...
tomcat启动spring工程
weixin_30781775的博客
05-21 93
BaseAction.java package com.ywb.action;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/baseAction")public...
spring容器启动过程
xrt95050的专栏
07-22 1235
什么时候spring容器启动? 其实就是程序中执行加载 xml配置文件的时候 1.应用程序下加载 ApplicationContext ctx = new ClassPathXmlApplicationContext("testspring2.xml"); 2.web模式下加载 web.xml:             contextConfigLocation      
Spring启动流程 及 SpringBoot怎么启动Tomcat
dayuiicghaid的博客
06-14 826
1.在创建Spring容器,也就是启动Spring时:2.首先会进行扫描,扫描得到所有的BeanDefinition对象,并存在一个Map中3.然后筛选出非懒加载的单例BeanDefinition进行创建Bean,对于多例Bean不需要在启动过程中去进行创建,对于多例Bean会在每次获取Bean时利用BeanDefinition去创建4.利用BeanDefinition创建Bean就是Bean的创建生命周期,这期间包括了合并BeanDefinition、推断构造方法、实例化、属性填充、初始化前、初始化、初始
Tomcat如何启动spring
zzd的博客
03-07 270
之前一篇博客说了tomcat怎么启动web项目。但是,现在绝大多数web项目都是用SSM框架写成的,那tomcat是如何启动war包里面的spring框架的呢? 详情还是看这个博文吧,链接是:https://blog.csdn.net/wuqinduo/article/details/99612285 ...
SpringMvc(零)- Tomcat启动SpringMvc
用针戳左手中指指头的博客
10-15 2963
本篇没有营养,只是记录的Tomcat启动的一个过程,非常粗略,目的是为了了解,Tomcat是怎么加载SpringMvc并启动SpringMvc的,基本上只记录了关键位置,比如创建关键对象、加载配置、及通知应用的方式等等。后续考虑深入研究下。
spring容器启动过程简要分析
jimware的专栏
04-18 3162
1、ContextLoaderListener 创建以及初始化在web.xml中配置org.springframework.web.context.ContextLoaderListener 的时候自动实例化ContextLoaderListener ,ContextLoaderListener类实现了javax.servlet.ServletContextListener接口,在web容器启动的...
深度解析:Spring Boot启动全过程
Spring Boot通过内嵌Servlet容器(如Tomcat或Jetty)以及自动配置功能,使得开发者能够快速地构建可执行的独立Java应用。 Spring Boot的启动通常始于一个主类,这个类通常包含一个`@SpringBootApplication`注解。当...
写文章

热门文章

  • TransactionSynchronizationManager用法和含义 43780
  • linux环境设置mysql的用户密码 15077
  • java -D简介 10451
  • spring事务隔离级别与数据库事务隔离级别的关系 10356
  • netty之NioEventLoopGroup 10343

分类专栏

  • 高并发 3篇
  • thrift 1篇
  • netty 3篇
  • CGlib 4篇
  • 加密算法 2篇
  • mycat 1篇
  • spring 49篇
  • Java 56篇
  • linux 17篇
  • redis 6篇
  • mysql 14篇
  • intellij 4篇
  • windows 3篇
  • tomcat 3篇
  • UltraEdit 1篇
  • excel 1篇
  • maven 5篇
  • svn 1篇
  • Apache 2篇
  • zookeeper 5篇
  • disconf 1篇
  • kafka 2篇
  • JVM 23篇
  • nginx 1篇
  • jdk特性原理解析 1篇
  • dubbo 13篇
  • 设计模型 12篇
  • 多线程 7篇
  • MQ 5篇
  • Spring cloud 2篇
  • mybatis 4篇
  • 网络通讯 7篇
  • 开发环境 4篇
  • 布隆过滤器 2篇
  • spring boot 5篇

最新评论

  • Spring 方法级别参数校验 之MethodValidationPostProcessor

    THE_FU: 调用步骤 controller ——》 serviceImpl方法1 —— 》 私有方法1(需要校验入参的方法)

  • Spring 方法级别参数校验 之MethodValidationPostProcessor

    THE_FU: 你好 我有个问题想问一下,在serviceimpl里有个私有方法想要校验参数 使用Validated 和 Valid都不生效 这是为什么

  • TransactionSynchronizationManager用法和含义

    weixin_peng: 毫无意义的博客

  • redis分布式锁事务解决方案

    a515370: redis.call('setnx', KEYS[1], ARGV[2]) 有问题, key没失效前不能解锁

  • spring是怎样管理mybatis的及注入mybatis mapper bean的

    中静~: 一个类实现了 spring的接口 并不会 交给spring管理 class B implements FactoryBean, InitializingBean 还需要 import 这个B,或者加上配置注解

大家在看

  • 蓝易云 - 在虚拟机Docker环境下部署Nginx的步骤。 371
  • 蓝易云 - Java编程技巧:<where>和<if>标签的组合使用示例 146

最新文章

  • docker 形态构建redis 哨兵模式集群
  • Netty 通信原理
  • Spring AOP 切入点表达式
2023年1篇
2022年2篇
2021年20篇
2020年43篇
2019年89篇
2018年42篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家长春市玻璃钢雕塑制作玻璃钢仿真动物雕塑厂家地址鞍山玻璃钢马雕塑平房玻璃钢雕塑定做玻璃钢广场小品雕塑摆件成都多彩玻璃钢雕塑商场美陈+招聘信息椰子美陈商场摊位图片崇左玻璃钢泡沫雕塑广东东莞专业玻璃钢雕塑厂家玻璃钢人物雕塑加盟昆虫玻璃钢雕塑淮北户外玻璃钢雕塑深圳清远玻璃钢卡通雕塑加工商场美陈用完都去哪里了玻璃钢商场美陈批发价玻璃钢雕塑图芒市玻璃钢烤漆雕塑定做商场舞台美陈玻璃钢着色雕塑商场美陈产品方案ppt稳定的玻璃钢景观雕塑达州玻璃钢雕塑摆件打造厂家泉州广场玻璃钢雕塑南京镜面玻璃钢雕塑性价比高玻璃钢桃子雕塑生产博山玻璃钢花盆花器玻璃钢雕塑前需要清洁什么深圳古代玻璃钢人物雕塑合肥户内玻璃钢雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化