springboot运行流程和实际应用

一、springboot运行流程

1、springboot获取配置的流程

在这里插入图片描述
上图是我对springboot获取配置流程的简单总结。

  • 运行主程序时,调用了@SpringBootApplication注解,这个注解又包含一个@Import注解,用于导入配置类。
  • 这个@Import注解会去类路径下所有的META-INF/spring.factories中去搜索以“AutoConfiguration”为后缀的配置类;
  • 对找到的每一个××AutoConfiguration配置类,根据其上的@EnableConfigurationProperties注解读取对于的××Properties类;
  • 将读取到的××Properties中的属性值绑定到组件中
  • 取用户配置文件,将配置的属性值绑定到组件中
  • 将组件在容器中注册。
    就这样完成了配置值的获取。

2、springboot启动流程

在这里插入图片描述
上图是我对springboot启动流程的简单总结。
运行主配置类时,主要分为两大步骤:首先创建Springboot的Application对象,然后是运行run方法。

2.1创建Springboot的Application对象

创建的对象根据springboot获取配置的流程,绑定了配置里面的默认值。
主要实现的功能就是到META-INF/spring.factories目录下去寻找两类东西并保存起来。

  • 一个是ApplicationContextInitializer,也就是容器的初始化器;
  • 一个是ApplicationListener,也就是应用程序的监听。
    保存的东西供run方法运行时调用。

2.2运行run方法

(1)去META-INF/spring.factories目录下去获取监听,注意获取的是ApplicationRunListener而不是ApplicationListener
(2)配置环境,然后调用上一步获取的监听的environmentPrepared方法表示环境准备完成
(3)创建ioc容器
(4)应用初始化器

  • 将配置好的环境在ioc容器中布置;
  • 读取创建Springboot的Application对象是保存的两类东西的方法,一个是初始化器,一个是contextPrepared方法,也就是告诉系统容器准备就绪。

(5)在ioc中注册命令行参数对象
(6)调用(1)获取的ApplicationRunListener中的contextLoaded方法表示上下文环境准备完成
(7)刷新容器:也就是获取、创建和加载所有的组件、配置类和自动配置类。
(8)从容器中获取ApplicationRunner和CommandLineRunner,并调用其中的run方法;
(9)调用(1)获取的ApplicationRunListener中的finished方法表示容器创建完成
(10)返回配置好的ioc容器

三、实际应用

1、基础配置应用

1.1在全局配置文件中配置端口号

server.port=8081

保存后重启项目即可生效。

1.2利用配置文件为javaBean赋值

1.2.1在全局配置文件中配置

(1)全局配置文件中的内容

#配置person的值
person.lastName-李四
person.age=18
person.birth=2019-12-14
#数组
person.lists=a,b,c
#dog的姓名和年龄
person.dog.name=lucky
person.dog.age=3

(2)测试类调用时使用@ConfigurationProperties注解来为person赋值

@ConfigurationProperties(prefix = "person")
@Component
public class Person {

这样Person类中对象的值就是配置类中的值。

1.2.2单独创建配置类

(1)创建的配置类person.property,里面的内容同上面全局配置文件
(2)测试类调用时使用@PropertySource注解来指定配置文件

@ConfigurationProperties(prefix = "person")
@Component
@PropertySource(value = {"classpath:person.properties"})
public class Person {

这样Person类中对象的值就是配置类中的值。

1.3利用@Value注解为单个属性赋值

//可以调用配置类中设置的值
@Value("${person.lastName}")
private String lastName;
//可以使用函数
@Value("#{11*2}")
private Integer age;
//可以直接赋值
@Value("true")
private Boolean boss;

1.4利用@Bean注解给容器中添加组件,达到配置的目的

//@Configuration指明当前类是配置类,替代之前的spring配置文件
//以前在配置文件中用<bean></bean>标签添加组件,在配置类中用@Bean注解替代
@Configuration
public class MyAppConfig {

    //将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService(){
        System.out.println("配置类@Bean给容器中添加组件了。");
        return new HelloService();
    }
}

1.5利用profile对不同环境提供不同配置

应用场景:一个项目在开发时和上线后的配置环境可能不同,通过profile可以方便的切换环境。

1.5.1profile文件形式

(1)properties文件格式

spring.profiles.active=dev

(2)yml文件格式

server:
  port: 8081
spring:
  profiles:
    active:dev
---
server:
  port: 8083
spring:
  profiles:dev

2、日志应用

2.1springboot默认日志框架

SpringBoot底层是使用slf4j+logback的方式进行日志记录;它凭借中间替换包可以把其他的日志都替换成slf4j;所以springboot能自动适配所有的日志。

2.2引入其他日志框架

引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;
举例:日志框架切换为log4j2

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring‐boot‐starter‐logging</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐log4j2</artifactId>
</dependency>

2.3日志的输出格式

日志输出格式

  • %d表示日期时间,
  • %thread表示线程名,
  • %‐5level:级别从左显示5个字符宽度
  • %logger{50} 表示logger名字最长50个字符,否则按照句点分割。
  • %msg:日志消息,
  • %n是换行符
    示例
%d{yyyy‐MM‐dd HH:mm:ss.SSS} [%thread] %‐5level %logger{50}%msg%n

2.4修改日志的默认配置

logging.level.com.atguigu=trace
#logging.path=
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=G:/springboot.log
# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;
#使用 spring.log 作为默认文件
logging.path=/spring/log
# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level 
    %logger{50}%msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy‐MM‐dd} === [%thread] === %‐5level 
    === %logger{50} ==== %msg%n

3、web开发

3.1静态资源的映射规则

3.1.1以jar包的方式调用静态资源

有些静态资源被打包成jar包供开发者调用,在maven中导入相关依赖后,就可以在相关jar包下的META-INF/resoured/webjars下面看到相关的静态资源。在浏览器中进行资源访问时,只需要写webjars下面的资源名称即可。
举例:引入jquery-webjar的依赖

<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>jquery</artifactId>
   <version>3.3.1-1</version>
</dependency>

引入jquery后的webjar路径
在这里插入图片描述
浏览器调用jquery.js:http://localhost:8080/webjars/jquery/3.3.1-1/jquery.js

3.1.2引入其他静态资源

在浏览器中输入“IP:端口/**”springboot都会去特定的五个目录下去寻找。

  • “classpath:/META‐INF/resources/”, 类路径下的/META-INF/resources/
  • “classpath:/resources/”, 类路径下的/resources/
  • “classpath:/static/”, 类路径下的/static/
  • “classpath:/public/” 类路径下的/public/
  • “/”:当前项目的根路径
    举例:在"classpath:/resources/",目录下导入静态资源
    在这里插入图片描述
    在浏览器中输入路径http://localhost:8080/asserts/js/Chart.min.js,可以查询到Chart.min.js,而不用xieresources目录。
3.1.3欢迎页的映射

浏览器中输入"/“或者”/index.html"时,springboot会自动在上述5个类路径下寻找index.html。

3.1.4喜爱图标的映射

浏览器打开页面后,页面的头部会有图标显示。若什么也不配置的情况下,springboot会去上述5个路径下去寻找名为“favicon.ico”的文件,找到后默认引用这个文件的图标作为所有未配置图标页面的图标。
在这里插入图片描述

3.2引入模板引擎thymeleaf

当页面是动态的时,可以通过模板引擎来将模板和数据进行整合,并按照模板的样式展示数据。
在这里插入图片描述

3.2.1引入thymeleaf
<!--引入Thymeleaf-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3.2.2thymeleaf应用

(1)在controller中添加数据

//查出一些数据在页面展示
@RequestMapping("/success")
public String success(Map<String,Object> map){
    map.put("hello","<h1>你好</h1>");
    map.put("users", Arrays.asList("zhangsan","lisi","wangwu"));
    //classpath:/templates/success.html
    return "success";
}

(2)编辑success.html文件

<body>
    <h1>成功!</h1>
    <!--th:text 将div里面的文本内容设置为-->
    <div th:text="${hello}">这是显示欢迎信息</div>
    <!--分界线-->
    <hr/>
    <div th:text="${hello}"></div>
    <div th:utext="${hello}"></div>
    <hr/>

<!--遍历-->
<!--th:each每次遍历都会生成当前这个标签:3个h4-->
    <h4 th:text="${user}" th:each="user:${users}"></h4>
    <hr/>
    <!--1个h4-->
    <h4>
        <span th:each="user:${users}">[[${user}]]</span>
    </h4>
</body>

(3)启动应用,浏览器输入网址
在这里插入图片描述

3.3视图映射方法引入资源

//使用WebMvcConfigureAdapter可以扩展springMVC的功能
//所有的WebMvcConfigureAdapter组件都会一起起作用
@Bean//将组件注册在容器中
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter(){
        public void addViewControllers(
            ViewControllerRegistry registry){
            registry.addViewController("/").setViewName("index");
            registry.addViewController("/index.html").
                setViewName("index");
        }
    };
    return adapter;
}

3.4拦截器的创建与注册

3.4.1拦截器创建
/**
* 登陆检查,
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
//目标方法执行之前
    @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("/index.html").
            forward(request,response);
        return false;
    }else{
    //已登陆,放行请求
        return true;
    }
}
3.4.2注册拦截器
//所有的WebMvcConfigurerAdapter组件都会一起起作用
@Bean //将组件注册在容器
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    WebMvcConfigurerAdapter adapter = 
        new WebMvcConfigurerAdapter() {
        @Override
        public void addViewControllers(
            ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").
            setViewName("login");
        registry.addViewController("/main.html").
            setViewName("dashboard");
        }

        //注册拦截器
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //super.addInterceptors(registry);
            //静态资源; *.css , *.js
            //SpringBoot已经做好了静态资源映射
            registry.addInterceptor(new
                LoginHandlerInterceptor()).addPathPatterns("/**")
            .excludePathPatterns("/index.html","/","/user/login");
         }
    };
    return adapter;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值