美文网首页
2019-02-14到2019-02-29

2019-02-14到2019-02-29

作者: 织雾呀 | 来源:发表于2019-02-28 15:58 被阅读0次

    我可没有断更

    模板引擎

    jsp freemark thymeleaf
    SpringBoot提供的thymeleaf模板引擎
    语法很简单,功能很强大
    下面这段代码路径为:


    image
    @ConfigurationProperties(
        prefix = "spring.thymeleaf"
    )
    public class ThymeleafProperties {
        private static final Charset DEFAULT_ENCODING;
        public static final String DEFAULT_PREFIX = "classpath:/templates/";
        public static final String DEFAULT_SUFFIX = ".html";
    
    

    语法:
    只要我们把html页面放在classpath:/templates/,thymeleaf就能自动渲染
    语法使用

    1.th:text  改变当前元素中的文本内容
        th:任意html属性:来代替原生属性
        
    
    
    image

    表达式语法:

    Simple expressions:
    Variable Expressions: ${...}
    Selection Variable Expressions: *{...}
    Message Expressions: #{...}
    Link URL Expressions: @{...}
    Fragment Expressions: ~{...}
    Literals
    Text literals: 'one text' , 'Another one!' ,…
    Number literals: 0 , 34 , 3.0 , 12.3 ,…
    Boolean literals: true , false
    Null literal: null
    Literal tokens: one , sometext , main ,…
    Text operations:
    String concatenation: +
    Literal substitutions: |The name is ${name}|
    Arithmetic operations:
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
    Boolean operations:
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
    Comparisons and equality:
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
    Conditional operators:
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
    Special tokens:
    Page 17 of 106No-Operation: _
    
    

    例如循环:

    <h4 th:text="${user}" th:each="user:${user}"></h4>
    <span th:each="user:${user}">[[${user}]]</span>
    

    SpringMVC自动配置

    官网的解释


    image

    27.1.1 Spring MVC Auto-configuration
    Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
    The auto-configuration adds the following features on top of Spring’s defaults:
    Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
    <font color="green">视图解析器:根据方法的返回值得到视图对象(view)是由视图对象决定如何渲染视图,重定向或者转发
    ContentNegotiatingViewResolver:组合所有的视图解析器
    如何定制视图:使用@bean给容器添加一个自定义的视图解析器;ContentNegotiatingViewResolver会自动将其组合进来 </font>
    Support for serving static resources, including support for WebJars (covered later in this document)).
    <font color="green">静态资源文件夹路径是webjars</font>

    Automatic registration of Converter, GenericConverter, and Formatter beans.
    Support for HttpMessageConverters (covered later in this document).
    Automatic registration of MessageCodesResolver (covered later in this document).
    Static index.html support.<font color="green">静态访问首页</font>
    Custom Favicon support (covered later in this document).
    Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
    If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
    If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.


    如何修改Spring Boot的默认配置
    : 1、Spring Boot在自动配置很多组件的时候,先看一下容器中有没有用户自己配置的(@Bean@component),如果有就用用户配置的,如果没有就使用默认配置
    如果有多个组件可以有多个(viewresolver)将用户配置和自己的配置组合进来
    2、在springboot中会有很多的xxxconfigraution帮助我们进行拓展
    3、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制


    SpringBoot国际化

    1、新建properties文件


    image

    2、Spring Boot自动配置好了管理国际化

    public MessageSourceAutoConfiguration() {
    }
    
    @Bean
    @ConfigurationProperties(
        prefix = "spring.messages"
    )
    

    application.properties/yml进行配置

    spring.messages.basename=i18n.login
    
    

    3、获取页面的值(模板引擎thymeleaf)

    效果根据浏览器的语言信息切换国际化。
    点中英文进行切换国际化的原理:
    : 国际化locale(区域信息对象):localeResolver
    SpringBoot在类WebMvcAutoConfiguration中配置了方法如下

    public LocaleResolver localeResolver() {
        if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.mvcProperties.getLocale());
        } else {
            AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
            localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
            return localeResolver;
        }
    }
    

    默认的就是根据请求头带来的区域信息后去locale进行国际化

    页面信息:

    <a th:href="@{/login.html(l='zh_CN')}">中文</a>
    <a th:href="@{/login.html(l='en_US')}">English</a>
    

    新建一个类继承LocaleResolver

    public class MylocaleResolver implements LocaleResolver {
    
        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            String l = request.getParameter("l");//获取页面语言参数
            Locale locale = Locale.getDefault();
            if(!StringUtils.isEmpty(l)){
                String[] split = l.split("_");
                locale = new Locale(split[0],split[1]);
            }
            return locale;
        }
        @Override
        public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {}
    }
    
    

    然后在被@Configuration修饰的类中进行注入

    @Bean
    public LocaleResolver localeResolver(){
        System.out.println("被注入");
        return new MylocaleResolver();
    }
    

    之后在页面点击链接就可以实现对应的效果了


    image

    登录:
    : 禁用模板引擎:

    spring.thymeleaf.cache=false
    

    页面修改之后Ctrl+f9;重新编译
    错误消息提示:

    <p th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
    

    防止表单重复提交,可以让请求重定向到主页


    IDEA设置热部署

    原文
    maven

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    

    IDEA设置


    image

    然后 Shift+Ctrl+Alt+/,选择Registry


    image
    ok了,重启一下项目,然后改一下类里面的内容,IDEA就会自动去make了。

    <font color="red">补充:</font>

    以上内容是网上大部分文章写的步骤,那发现并非一定实现(似乎和spring boot的版本有关系)。如果按照以上流程配置后

    修改Html后ctrl+s 内容依然没变,application.yml加上以下配置即可

    spring:
      devtools:
          restart:
            #需要实时更新的目录
            additional-paths: resources/**,static/**,templates/**
    

    SpringBoot拦截器

    新建类实现接口HandlerInterceptor,然后添加对应的方法

    public class LoginHandlerInterceptor implements HandlerInterceptor {
    
        /**
         * 目标执行之前
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Object user = request.getSession().getAttribute("loginUser");
            if(user==null){
                //未登录
                //未登录返回登录页面
                request.setAttribute("msg","没有权限请先登录!!");
                request.getRequestDispatcher("/").forward(request,response);
            }else{
                //已登录,放行请求
                return true;
            }
            return false;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
    

    再在配置类中进行配置

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/index/**");
        }
    }
    

    就可以了哦


    CRUD员工列表

    要求
    1.restfulCRUD:CRUD要满足rest风格
    : URI:资源名称/资源标识 http请求方式区分CRUD的操作


    普通的CRUD RESTFUL风格的CRUD
    查询 getEmp emp--GET
    添加 addEmp?xxx emp--POST
    修改 updateEmp?id=xxx emp--PUT
    删除 deleteEmp?id=xxx emp--DELETE

    2.请求框架


    请求URL 请求方式
    查询所有员工 emps GET
    查询单个员工 emp/1 GET
    来到添加页面 emp GET
    添加页面 emp POST
    来到修改页面(查询员工进行信息回显) emp/1 GET
    修改员工 emp PUT
    删除员工 emp/1 DELETE

    抽取公共片段


    配置嵌套式Servlet容器

    SpringBoot2中已经做了改动,文章:聊聊springboot2的embeded container的配置改动

    : SpringBoot默认的是Tomcat作为嵌入式servlet
    问题:
    : 1、如何定制和修改Servlet容器的相关配置
    修改Servlet有关的配置

    #进行配置
    server.xxx=xxx
    server.port=端口号
    修改tomcat的配置
    server.Tomcat.xxx = 修改Tomcat的配置
    
    

    编写嵌入式Servlet容器的定制器;主要作用就是修改servlet的配置,下面的是SpringBoot2的方法,在配置类中进行编写

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer ,WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    
        @Override
        public void customize(ConfigurableServletWebServerFactory factory) {
            ((TomcatServletWebServerFactory)factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
    //                Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    //                protocol.setMaxConnections(200);
    //                protocol.setMaxThreads(200);
    //                protocol.setSelectorTimeout(3000);
    //                protocol.setSessionTimeout(3000);
    //                protocol.setConnectionTimeout(3000);
                    connector.setPort(8085);
                }
            });
        }
    }
    
    

    注册Servlet的三大组件
    servlet
    filter
    Listener
    由于SpringBoot是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件
    ServletRegistrationBean
    FilterRegistrationBean
    ServletListenerRegistrationBean
    在注册三大组件的时候用以下方式
    例:filter

    public class MyServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("hello MyServlet");
        }
    }
    
    

    配置类:

    @Configuration
    public class MyServletConfig implements WebMvcConfigurer {
        @Bean
        public ServletRegistrationBean myServlet(){
            ServletRegistrationBean servletRegistrationBean = new
                    ServletRegistrationBean(new MyServlet(),"/myservlet");
            return servletRegistrationBean;
        }
    }
    
    

    页面效果:


    image

    过滤器:

    public class MyFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("MyFilter process...");
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
    

    配置类进行注册:

    
    
    

    2、Spring Boot能不能支持其他的Servlet容器
    jetty(长连接)
    undertow(不支持jsp)
    切换方法:
    更换pom.xml文件

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <groupId>org.springframework.boot</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jetty -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
        <version>2.1.3.RELEASE</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-undertow -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
        <version>2.1.3.RELEASE</version>
    </dependency>
    
    

    使用外置的servlet容器

    : 嵌入式的servlet:把应用打成jar包
    优点:简单,便携
    缺点:不支持jsp(工作)

    解决办法:
    : 配置一个外置的servlet容器:外面安装一个tomcat应用war包的方式打包

    1、创建一个war包项目(使用IDEA创建目录结构)
    2、将嵌入式的tomcat指定为provided

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    
    

    3、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

    public class ServletInitializer extends SpringBootServletInitializer {
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(SpringBootWarApplication.class);
        }
    }
    

    4、启动服务器就可以使用了


    IDEA配置springboot的外置servlet容器

    新建springboot项目,配置生成webapp目录


    image
    image

    外置tomcat配置的端口号不能和springBoot配置的端口重复!


    SpringBoot与Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

    image

    docker的安装

    查看centos版本
    uname -r
    升级软件包及内核
    yum update
    安装docker
    yum install docker
    启动docker
    systemctl start docker
    将docker设为开机启动
    systemctl enable docker
    停止docker
    systemctl stop docker

    docker核心概念

    : docker主机(Host):安装了docker程序的机器(Docker直接安装在操作系统之上)
    docker客户端(Client):连接docker主机及进行操作(mysql)
    docker仓库:docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。
    docker镜像:软件打包好的镜像放到仓库中让别人使用
    docker容器(Container):镜像启动后的实例称为一个容器。容器是独立运行的,一个或一组。

    使用docker

    : 1、安装Docker
    2、去docker仓库找到软件相应的镜像
    3、使用Docker运行镜像,这个镜像就会生成一个docker容器
    4、对镜像的启动或者停止就是对软件的启动或停止。

    安装Docker

    : 1、安装linux系统
    2、在linux上安装Docker


    SpringBoot原理

    几个重要的事件回调机制
    : 执行ApplicationContextInitializer,initialize()
    监听器SpringApplicationRunListener回调contextPrepared
    加载主配置类定义信息
    监听器SpringApplicationRunListener回调contextLoaded

    启动流程:
    1、创建一个SpringApplication对象
    : 判断当前应用是否是web应用
    从类路径下查找META-INF/spring.factories配置所有的applicationContextInitialize,然后保存起来

    public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {
        this.listeners = new ArrayList();
        this.listeners.addAll(listeners);
    }
    

    从类路径下查找META-INF/spring.factories配置所有的applicatonListeners

    private Class<?> deduceMainApplicationClass() {
        try {
            StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
            StackTraceElement[] var2 = stackTrace;
            int var3 = stackTrace.length;
    
            for(int var4 = 0; var4 < var3; ++var4) {
                StackTraceElement stackTraceElement = var2[var4];
                if ("main".equals(stackTraceElement.getMethodName())) {
                    return Class.forName(stackTraceElement.getClassName());
                }
            }
        } catch (ClassNotFoundException var6) {
            ;
        }
    
        return null;
    }
    
    

    从多个主配置类中找到有main方法的主配置类

    2、运行run方法
    : 获取SpringApplicationRunListeners从类路径下MATE-INF/spring.factories

    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    //回调SpringApplicationRunListeners.starting()方法
    listeners.starting();
    

    封装命令参数

    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    

    准备环境

    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
                this.configureIgnoreBeanInfo(environment);
                //创建applicationcontext,决定创建web的ioc还是普通的ioc
                Banner printedBanner = this.printBanner(environment);
                context = this.createApplicationContext();
                //准备上下文环境,将enviroment保存到ioc中,而且applicationInitizer
                exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
                this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
                //扫描创建加载所有的组件的地方
                this.refreshContext(context);
                //applicatonRunner先回调,commandLinerRunner再回调
                this.afterRefresh(context, applicationArguments);
                
                stopWatch.stop();
                if (this.logStartupInfo) {
                    (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
                }
    
                listeners.started(context);
                this.callRunners(context, applicationArguments);
            } catch (Throwable var10) {
                this.handleRunFailure(context, var10, exceptionReporters, listeners);
                throw new IllegalStateException(var10);
            }
    
    

    启动原理:

    SpringApplication.run(主程序类)
    new SpringApplication(主程序类)
    : 判断是否web应用
    加载并保存所有的ApplicationContextInitializer(META-INF/spring.factories)
    加载并保存所有的ApplicationListener
    获取到主程序类

    run()
    : 回调所有的SpringApplicationRunListener(META-INF/spring.factories)的staring
    获取ApplicationArguments
    准备环境&回调所有的监听器(SpringApplicationRunListener)的environmentPrepared
    打印banner信息
    创建ioc容器对象(
    AnnotationConfigEmbeddedWebApplicationContext(web环境容器)
    AnnotationConfigApplicationContext(普通环境容器)

    相关文章

      网友评论

          本文标题:2019-02-14到2019-02-29

          本文链接:https://www.haomeiwen.com/subject/nwxkuqtx.html