精华内容
下载资源
问答
  • 外置和内嵌tomcat区别 外置tomcat: tomcat启动加载web.xml,通过web.xml配置初始化spring容器,并加载dispatcherservlet 内嵌tomcat: springboot启动,初始化spring容器加载bean,然后启动内嵌tomcat,通过...

    外置和内嵌tomcat区别

    外置的tomcat:
    tomcat启动加载web.xml,通过web.xml配置初始化spring容器,并加载dispatcherservlet
    内嵌tomcat:
    springboot启动,初始化spring容器加载bean,然后启动内嵌tomcat,通过servlet3.1规范的  ServletContainerInitializer加载dispatcherservlet

    代码示例及流程说明

    我会一边贴出代码,一边解释下部分代码

    git地址:https://gitee.com/chuanxin1123/yboot

    项目结构:

    首先是maven依赖:

      <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
                <version>8.5.23</version>
            </dependency>

    那么我们在这里分析一下springboot启动流程:

    1.初始化ioc

    为什么要先初始化ioc,而不是先启动tomcat?因为ioc是必须的,而tomcat可以被其他中间件替换

    2.启动tomcat

    3.将dispatcherServlet放入到ioc容器,并加载到tomcat上下文中去

    那么我们先实现第一步:初始化ioc

    @ComponentScan("com.chuan")
    public class StartApplication {
        public static void main(String[] args) throws Exception{
            //1.初始化ioc,
            // 为什么要先初始化ioc,而不是先启动tomcat,因为ioc是必须的,而tomcat可以被其他中间件替换
            AnnotationConfigWebApplicationContext ac=new AnnotationConfigWebApplicationContext();
            ac.register(StartApplication.class);   //手动去注册一个bean
            ac.refresh();                          //刷新
           
        }
    }

    然后将dispatcherServlet注入到ioc中,这里为什么不能写在主方法中?因为写在主方法中就是强引用了,必须要使用servlet方式处理并且必须是web项目了。

    @Configuration
    public class MyConfig {
        @Bean
        public DispatcherServlet getDispatcherServlet(){
            return new DispatcherServlet();
        }
    
    
    }

    实现第二步:启动tomcat,写一个接口和tomcat实现类

    public interface WebServerFactory {
        //使用接口增加了扩展性,不一定非要用tomcat
        void createServer() throws Exception;
    }
    @Component
    public class MyTomcat implements WebServerFactory{
        public void createServer() throws Exception {
            Tomcat tomcat=new Tomcat();
            tomcat.setPort(8081);
            tomcat.addWebapp("/","D://soft");
            tomcat.start();
            //因为  tomcat.start();是非阻塞型的,所以要阻塞一下,不能让服务停止。
            tomcat.getServer().await();
        }
    }

    然后修改主方法,调用tomcat启动

    @ComponentScan("com.chuan")
    public class StartApplication {
        public static void main(String[] args) throws Exception{
            //1.初始化ioc,
            // 为什么要先初始化ioc,而不是先启动tomcat,因为ioc是必须的,而tomcat可以被其他中间件替换
            AnnotationConfigWebApplicationContext ac=new AnnotationConfigWebApplicationContext();
            ac.register(StartApplication.class);   //手动去注册一个bean
            ac.refresh();                          //刷新
            //2.启动tomcat
            WebServerFactory factory = ac.getBean(WebServerFactory.class);
            factory.createServer();
            //3.将dispatcherServlet放入到ioc容器,并加载到tomcat上下文中去
            //注意dispatcherServlet不能放在启动里,因为也可以被reactive响应式编程替换掉servlet,也可以不是web项目
    
        }
    }

    但现在tomcat和dispatcherServlet并没有关联起来,需要进行第三步操作:将dispatcherServlet放入到ioc容器,并加载到tomcat上下文中去

    创建一个servlet作为顶层servlet,实现了一个ApplicationContextAware 接口。

    ApplicationContextAware接口中setApplicationContext方法让Spring容器传递自己生成的ApplicationContext给我们使用,然后通过ac获取到DispatcherServlet的实例。

    @Component
    public class MyServlet implements ApplicationContextAware {
        private static ApplicationContext context;
        
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context=applicationContext;
        }
        //从ac中获取实例
        public static DispatcherServlet getDispatcherServlet(){
            return context.getBean(DispatcherServlet.class);
        }
    }

    然后通过子类将DispatcherServlet添加到tomcat上下文中去。

    这里有两种写法:

    1.实现WebApplicationInitializer接口(springboot封装了ServletContainerInitializer接口)

    2.实现ServletContainerInitializer接口(spi3.0规范)

    从servlet3.0开始,web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。每个框架要使
    用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的
    ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。

    实现了onStartup后,在运行中会自动执行该方法,也正是该方法替代了spring中的web.xml,实现了无配置。

    写法1:

    public class MyServletInit extends MyServlet implements WebApplicationInitializer {
    
        public void onStartup(ServletContext servletContext) throws ServletException {
            ServletRegistration.Dynamic dynamic =servletContext.addServlet("MyDispatcherServlet",super.getDispatcherServlet());
            dynamic.setLoadOnStartup(1);
            dynamic.addMapping("/");
        }
    }

    写法2:

    public class MyServletInit extends MyServlet  implements  ServletContainerInitializer {
        @Override
        public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
            ServletRegistration.Dynamic dynamic =servletContext.addServlet("MyDispatcherServlet",super.getDispatcherServlet());
            dynamic.setLoadOnStartup(1);
            dynamic.addMapping("/");
        }
    }

    但需要多出一步,在resources下创建一个META-INF/services目录(不是一个叫META-INF.services的文件夹),在该目录下创建一个文件名为javax.servlet.ServletContainerInitializer的文件,里面内容为该实现类的全路径(我的spi3.0实现是简写了)

    com.chuan.config.MyServletInit

    最后写一个controller启动:

    @RestController
    public class MyController {
        @RequestMapping("/test")
        public String test(){
            return "test";
        }
    }

    结果:启动成功,并且DispatcherServlet功能也正常。

    什么替换了web.xml

    比如通过web.xml方式启动:

    <web-app>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <servlet>
    <servlet-name>app</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/*</url-pattern>
    </servlet-mapping>
    </web-app>

    其中的ContextLoaderListener可以被下面代码替代

       AnnotationConfigWebApplicationContext ac=new AnnotationConfigWebApplicationContext();
            ac.register(StartApplication.class);   //手动去注册一个bean
            ac.refresh();  

    而DispatcherServlet则可以被下面代码替代

     ServletRegistration.Dynamic dynamic =servletContext.addServlet("MyDispatcherServlet",super.getDispatcherServlet());
            dynamic.setLoadOnStartup(1);
            dynamic.addMapping("/");

     

    展开全文
  • 小程序h5的区别是什么?主要在于这几点:(1)开发方法不同。H5的开发工具依赖的外壳主要是浏览器,因此只要有浏览器,就可以使用。比如手机内置的浏览器,APP 的 web-view 组件,以及小程序提供的 web-view 组件,...
    e4bd9d7e4dd189e3bbdf73b19a567aa2.png你了解微信小程序吗?小程序和h5的区别是什么?主要在于这几点:(1)开发方法不同。H5的开发工具依赖的外壳主要是浏览器,因此只要有浏览器,就可以使用。比如手机内置的浏览器,APP 的 web-view 组件,以及小程序提供的 web-view 组件,都可以打开 H5 页面。小程序的开发则是使用开发工具,可以用官方的开发者工具(适合码农),也可以用第三方小程序制作工具(适合纯小白),比如「上线了」sxl.cn00fb0d6fd42e6dc5ec8b4162c42e3b25.png

    本展示页所提供的模板及元素仅供展示功能效果,

    未经授权不得应用于其他用途      

    (2)打开方式不同。微信小程序只能在微信APP内打开;而h5页面可以在各种浏览器上打开。(3)浏览体验不同。小程序要快很多,这是因为小程序基于微信客户端实现,对解析进行了优化,并且一旦首次打开小程序,可以直接缓存很多资源。再加上小程序的设计理念本就是“小而轻”,希望能带给访客快捷省时的使用体验。2cdaf8d85b89c9e19feff67796eafc7d.png上线了小程序案例,禁止转载而 H5 本质上还是网页,跟之前在 PC 上浏览网页没区别,每次要请求各种图片样式资源,在浏览器内核里渲染,因此体验会差一些。有些开发者在开发小程序时,想要小程序跳转h5、小程序内嵌h5页面功能,这种情况下可以参考以下web-view组件:https://developers.weixin.qq.com/miniprogram/dev/component/web-view.htmlh5跳小程序就简单了,你可以直接在网页中附上小程序码的图片,让访客扫描就好。以上就是关于h5小程序区别、开发问题科普了,如果你想快速拥有一个小程序,可以使用「上线了」sxl.cn小程序制作工具哦,不需要懂任何技术!点击下方“阅读原文”,用「上线了」制作一个自己的小程序试试吧!(电脑端操作更方便哦)「上线了sxl.cn」是一个专注自助建站与小程序开发的SaaS平台,针对众多行业提供多套小程序模板,目前已经帮助三百多万没有技术和设计基础的用户,通过上线了一键生成网站或小程序,快速建立品牌、获取客户、经营生意。2019年8月入选腾讯SaaS加速器首期成员。a7054c61f42a9cd95acd770a5ec55775.png推荐阅读85489da29d78ee88f88f9160b30b2d0a.png小程序商城圣诞跨年营销方案 1f539e200e61319950fbe4e852adbe4f.png网站商家圣诞节跨年营销方案 d03f2ffc960683ee3c6bd82e7aec1f48.png高质量小程序样式模板大全 
    展开全文
  • PHP支持内嵌HTML, 那么对于PHP文件中, PHP标签外的HTML会怎么处理呢? 它直接输出HTML有什么区别么?
  • PHP支持内嵌HTML, 那么对于PHP文件中, PHP标签外的HTML会怎么处理呢? 它直接输出HTML有什么区别么?PHP提供了一个错误抑制符’@, 它是通过什么方式来阻止错误输出呢? 我又该在什么时候使用它呢?PHP文件内嵌HTML...

    PHP支持内嵌HTML的, 那么对于PHP文件中, PHP标签外的HTML会怎么处理呢? 它和直接输出HTML有什么区别么?

    PHP提供了一个错误抑制符’@', 它是通过什么方式来阻止错误输出呢? 我又该在什么时候使用它呢?

    PHP文件内嵌HTML的处理方式

    在PHP中, 所有在标签外的字符, 在词法分析过程中, 都会翻译成T_INLINE_HTML token, 在语法分析的时候, 所有的T_INLIE_HTML都会被分配ZEND_ECHO输出.

    也就是说:

       1. <?php
       2. while($con) {
       3. ?>
       4. laruence
       5. <?php
       6.  }
       7. ?>

    会生成一条OPLINE: T_ECHO, 而操作数是”laruence”;

    就结果来说, 上面的代码, 其实和下面的结果一样:

       1. <?php
       2.  while($con) {
       3.    echo "laruence";
       4.  }
       5. ?>

    但有一个要注意的地方是, 对于PHP标签外的字符, 在词法分析过程中, 都会以400个字符为单位切分, 比如:

       1. <?php
       2.     if(1) {
       3. ?>
       4. laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence laruence
       5.  <?php
       6.     }
       7. ?>

    上面的代码中, 标签外有531个字符(包含空格回车), 会被分成俩条T_INLINE_HTML输出.

    错误抑制符

    我们知道,在PHP中,可以通过错误抑制符来静默错误提示, 那么它是通过什么方式呢?

    在语法分析的过程中, 对于:

       1. <?php
       2.      @include('file');
       3. ?>

    会分别在include语句前后插入俩条Opline(操作), 这俩个操作分别做:

       1. 1. 保存当前的error_reporting值, 并设置error_reporting(0); //关闭错误输出
       2. 2. 恢复之前保存的error_reporting值.

    也就是说, 其实上面的代码, 和下面的代码类似:

       1. $old = error_reporting(0);
       2. include('file');
       3. error_reporting($old);

    另外, 讲一句题外话:”什么时候才应用错误抑制呢?”, 我个人建议, 就是如果这条语句出错了对你影响不大, 你也不关心这个错误是什么, 你也不会安排额外的逻辑来处理这种错误, 那么你可以使用错误抑制. 否则, 请你使用额外的逻辑来判断错误.

    展开全文
  • link@import的区别

    2017-03-18 16:33:10
    页面中使用CSS方式主要有3种:行内添加定义style属性值,页面头部内嵌调用外面链接调用,其中外面引用有两种:link@import。外部引用CSS两种方式link@import方式分别是: XML/HTML代码   XML/HTML代码  ...

    页面中使用CSS的方式主要有3种:行内添加定义style属性值,页面头部内嵌调用和外面链接调用,其中外面引用有两种:link和@import。外部引用CSS两种方式link和@import的方式分别是:

    XML/HTML代码
       
    XML/HTML代码
      

    两者都是外部引用CSS的方式,但是存在一定的区别:

      区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。

      区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。

      区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。

      区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。

    补充:@import最优写法
    @import的写法一般有下列几种:

    @import 'style.css' //Windows IE4/ NS4,Mac OS X IE5, Macintosh IE4/IE5/NS4不识别
    @import "style.css" //Windows IE4/ NS4, MacintoshIE4/NS4不识别
    @import url(style.css) //Windows NS4, Macintosh NS4不识别
    @import url('style.css') //Windows NS4, Mac OS X IE5, MacintoshIE4/IE5/NS4不识别
    @import url("style.css") //Windows NS4, Macintosh NS4不识别
    由上分析知道,@import url(style.css) 和@import url("style.css")是最优的选择,兼容的浏览器最多。从字节优化的角度来看@importurl(style.css)最值得推荐。

    展开全文
  • link@import的区别是 : ①link属于XHTML标签,除了加载CSS,还能 用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS; ②页面被加载的时,link会同 时被加载,而@import引用的CSS...
  • link@import的区别:(1)link是XHTML标签,除了加载CSS,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。(2)link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。(3)...
  • 引入方式3种:行内添加定义style属性值,页面头部内内嵌调用外链调用, 区别: 1.link是xhtml标签,除了加载css,还可以定义RSS等其他事务,@import只能加载CSS 2.link引用CSS时候,页面载入时候同时...
  • link与@impoort的区别 link属于html标签,而@import是CSS提供的。link除了加载CSS,还能用于定义RSS,定义rel链接属性等作用;而@import是CSS提供的,只能用于加载CSS。 import是CSS2.1提出的.
  • PSAM卡(Purchase Secure Access Module,销售点终端安全存取模块),内嵌于各类终端设备,为其提供IC卡级别安全保护, PSAM除具备用户卡功能,还具有计算功能。PSAM中增加了计算型密钥。PSAM主要应用于商用POS,...
  • link与@import的区别

    2017-09-12 15:18:05
    在HTML中引入CSS方法主要有四种,分别是行内样式、内嵌样式、链接样式、导入样式,其中外部引入两种就是链接样式导入样式,也就是linkimport。 1、示例 XML/HTML代码 XML/HTML代码 @import url("CSS...
  • PSAM卡指终端安全控制模块,内嵌于各类终端设备,为其提供IC卡级别安全保护,PSAM除具备用户卡功能,还具有计算功能。PSAM中增加了计算型密钥。应用范围PSAM主要用于商用POS[销售终端-pos(pointofsale)是一种多...
  • Exynos4412 所用存 —— eMMC

    千次阅读 2016-03-03 22:30:31
    Exynos4412所用存不是原来... eMMC(Embeded MultiMedia Card):它并非是一种全新尺寸存储卡,而是由MMC协会所订立的内嵌式存储器标准规格,而且还是专门为手机移动嵌入式产品设计。eMMC简单来说是一个
  • Hive基础(1)

    2016-04-17 18:17:51
    2. 元数据数据的区别,前者如表名、列名、字段名等。3. Hive的三种安装方式 内嵌模式,元数据服务Hive服务运行在同一个JVM中,同时使用内嵌的Derby数据库作为元数据存储,该模式只能支持同时最多一个用户打开...
  • CSS一些问题

    2015-04-01 09:33:26
    link@import的区别是? 内联 内嵌 外链 导入 link@import的区别是: @import url("CSS文件"); 两者都是外部引用CSS的方式,但是存在一定的区别:  区别1:link是XHTML标签,除了加载CSS,还可以...
  • HTML8 工作总结

    千次阅读 2017-05-22 15:54:08
    其实text-shadow和box-shadow差别不大,其中重点要区别的内嵌阴影和外阴影,以及掌握参数含义就好了。这里重点说下内嵌阴影,它格式如下: box-shadow: inset npx mpx kpx color 其中n,m分别是阴影在水平...
  • 尽我所知,除了文中特别加以标注致谢地方,论文中不包含其他人已经发表或撰写过研究成果,也不包含为获得东南大学或其它教育机构学位或证书而使用过材料。与我一同工作同志对本研究所做任何贡献均已...
  • 一.spring---spring-boot的区别 其实讲区别,就是讲spring-boot有不同Spring Boot可以建立独立的Spring应用程序;内嵌了如Tomcat,JettyUndertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。无需...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

内嵌和外嵌的区别