继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

SpringBoot 之基础学习篇.

MMMHUHU
关注TA
已关注
手记 288
粉丝 26
获赞 98

一、概念简介

    SpringBoot 的关键词是“约定俗成”,它根据长久以来的 Spring 开发配置经验,整理出一套适用、普遍、大家都认可的配置方案。所以 SpringBoot 的学习过程中心态一定要放宽,没必要太去钻牛角尖,重点是配置和自定义...

    Spring Boot 简化了基于Spring的应用开发,为Spring平台及第三方库提供了开箱即用的设置,你只需要“run”就能创建一个独立的,产品级的 Spring 应用。

    SpringBoot 的 Startsers 是以一个依赖描述符的集合,包含了很多搭建,快速运行项目所需要的依赖,并提供一致的,可管理传递性的依赖集。你可以获取所有 Spring 及相关技术的一站式服务,而不需要翻阅示例代码,拷贝粘贴大量的依赖描述符。所有官方的 starters 遵循相似的命名模式:spring-boot-starter-* 。

    SpringBoot 的 Auto-configuration 设计成可以跟 Starters 一起很好的使用,AutoConfiguration 会根据你所依赖的 jar 包,会尽最大努力去自动配置你的应用。

    Spring Boot 每次发布都关联一个 Spring 框架的基础版本,所以强烈建议你不要自己指定Spring版本。

回到顶部

二、spring-boot-devtools 开发者工具

    spring-boot-devtools 是 SpringBoot 中内置的一个开发者工具 ,用于自重启,功能当然没有 Jrebel 那么强大,但正常的开发也差不多够用了。spring-boot-devtools 默认检测 classpath 路径下的文件,只要目录下的文件有变动,它就会自动重启。

    自动重启跟 LiveReload 可以一起很好的工作。

    如果你使用 JRebel,自动重启将禁用以支持动态类加载。

    1、Maven 依赖

复制代码

        <!--
             1、在运行一个完整的,打包过的应用时(Java -jar),会禁用开发者工具。
             2、防止 devtools 传递到项目中的其他模块,需要设置依赖级别 optional
             3、只要 classpath 下的文件有变动(Eclipse 中文件保存就能重启,IDEA 中需要 Build ——> Build Project),系统就会自动重启。        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

复制代码

    2、application.yml 配置

复制代码

spring:
  devtools:
    restart:      # devtools 排除不需要检测的资源 和 增加额外需要监测的资源      exclude: application.yml
      additional-paths: src/main/webapp      # 是否重启,如果设置为false禁用,依旧会初始化重启类加载器,但它不会监控文件变化      enabled: true      # 触发器文件,只有在修改该文件的时候,才能触发工程重启
      #trigger-file: trigger-file    livereload:      # 内嵌的 LiveReload 服务器,可以在资源改变时,触发浏览器更新,禁用设置为false
      enabled: true

复制代码

    3、spring-boot-devtools 和 LiveReload 搭配使用

    LiveReload 是一个 spring-boot-devtools 模块中的内嵌服务器,它可以在资源改变时触发浏览器更新,LiveReload 浏览器扩展的谷歌插件下载地址:https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei ,如果不想使用该功能的话,可以在 application.yml 中禁用,如上。这工具还是很值得推荐的,可以大大的节约开发时间。

回到顶部

三、SpringApplication

     SpringApplication 姑且称它为 SpringBoot 的引导类吧!它将为我们创建正确类型的 Spring 上下文 ApplicationContext 。默认情况下,SpringApplication 根据我们开发的是否为web应用(可以手动指定是否为 Web 应用)决定使用 AnnotationConfigApplicationContext 或 AnnotationConfigEmbeddedWebApplicationContext。除此之外,SpringApplication 还有一些无关痛痒的设置,比如:是否打印 Banner 这些的。

    常常需要在 SpringApplication 加载前或者退出后做一些相关的操作,比如初始化一些信息,关闭一些流、文件 什么的。怎么实现呢?

    实现 CommandLineRunner 或者 ApplicationRunner 接口可以在 SpringApplication 启动后,run() 方法运行前执行一些特殊的代码。
    实现 ExitCodeGenerator 接口可以在 Application 退出后返回特殊的特征码,用于 SpringApplication.exit() 时使用。
    实现 DisposableBean 接口,用于在 SpringApplication 退出后(SpringApplication.exit())实现自己的一些逻辑,或者使用 @PreDestroy 注解。

@Componentpublic class ApplicationArgumentsBean implements CommandLineRunner, ApplicationRunner, ExitCodeGenerator, DisposableBean {    private static final Logger logger = LoggerFactory.getLogger(ApplicationArgumentsBean.class);    /**
     * 如果运行的时候使用 java -jar *.jar --debug logfile.txt
     * 则:debug = true,files=["logfile.txt"]
     *
     * @param args     */
    @Autowired    public ApplicationArgumentsBean(ApplicationArguments args) {        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
    }

    @Override    public void run(ApplicationArguments args) throws Exception {
        logger.info("重写 ApplicationRunner 的 run 方法:{}", args.containsOption("debug"));
    }

    @Override    public void run(String... args) throws Exception {
        logger.info("重写 CommandLineRunner 的 run 方法:{}", args);
    }

    @Override    public int getExitCode() {        return 0;
    }

    @Override    public void destroy() throws Exception {
        logger.info("重写 DisposableBean 的 destroy 方法,用于在 SpringApplication 退出后执行一些操作");
    }

    @PreDestroy    public void predestroy() {
        logger.info("使用 @PreDestroy 用于在 SpringApplication 退出后执行一些操作");
    }
}

ApplicationArgumentsBean.java

复制代码

@EnableAutoConfiguration
@Configuration
@ComponentScanpublic class Example {    
    public static void main(String[] args) {        // 我们需要将Example.class作为参数传递给run方法,以此告诉SpringApplication谁是主要的Spring组件
        SpringApplication app = new SpringApplication(Example.class);        // 手动调用setWebApplicationType() 指定为 web 应用        app.setWebApplicationType(WebApplicationType.SERVLET);        // 设置打印 Banner 的方式        app.setBannerMode(Banner.Mode.LOG);        // 是否将启动时的命令行属性添加到 Environment
        app.setAddCommandLineProperties(true);
        ConfigurableApplicationContext run = app.run(args);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override            public void run() {
                SpringApplication.exit(run, (ExitCodeGenerator) run.getBean("applicationArgumentsBean"));
            }
        });
    }
}

复制代码

tips:建议将应用的main类放在其他类所在包的顶层(root package)。

回到顶部

四、引入外部配置文件

    SpringBoot 的默认配置文件是 application.yml 或者 application.properties,如果想要引入其他的 properties 文件 或者 yml 文件,该怎么操作呢?

    1、properties 文件

    properties 文件引入较为简单,跟 Spring 一样。在配置类上使用 @PropertySource 注解引入,在其他地方使用 @Value 注解读取。

    2、yml 文件

    我们先从 SpringBoot 的默认配置文件 application.yml 文件聊起,application.yml 的文件内容,是可以通过 @Value 的方式读取到的,比如 @Value("${server.port}") 这样。究其原因的话,应该是 SpringBoot 底层把 ApplicationContext 注册进 PropertySourcesPlaceholderConfigurer 导致的吧!

    那么我们自定义的 yml 文件要怎么引入呢?看了网上的一些教程,很多人推荐用如下这种方式:

复制代码

    @Bean    public PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new ClassPathResource("my.yml"));
        configurer.setProperties(yaml.getObject());        return configurer;
    }

复制代码

    这种方式,确实可以用,通过这种方式把 yml 文件加载到 PropertySourcesPlaceholderConfigurer 后,通过 @Value 方式读取到属性值。但是!但是!原来的 application.yml 中的 @Value 属性全获取不到了,我猜想是不是 Bean 覆盖导致的,我试着手动把 application.yml 和 my.yml 都加载进 PropertySourcesPlaceholderConfigurer ,以及使用 @Primary 注解,结果都不管用!所以就放弃了这种做法。

    那要怎么加载我们自定义的 yml 文件呢 ?通过 YamlPropertiesFactoryBean 或者 YamlMapFactoryBean 类:

复制代码

    @Test    public void test3() {
        YamlPropertiesFactoryBean yml = new YamlPropertiesFactoryBean();
        yml.setResources(new ClassPathResource("my.yml"));
        Properties properties = yml.getObject();
        Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();        while (iterator.hasNext()) {
            Map.Entry<Object, Object> entry = iterator.next();
            logger.info("YamlPropertiesFactoryBean 读取的配置文件内容是:{}-{}", entry.getKey(), entry.getValue());
        }

        logger.info("--------华丽的分割线------------");

        YamlMapFactoryBean yamlMapFactoryBean = new YamlMapFactoryBean();
        yamlMapFactoryBean.setResources(new ClassPathResource("my.yml"));
        Map<String, Object> map = yamlMapFactoryBean.getObject();
        Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            logger.info("YamlPropertiesFactoryBean 读取的配置文件内容是:{}-{}", entry.getKey(), entry.getValue());
        }
    }

复制代码

    另外需要提及的是 SpringBoot 还提供了 @ConfigurationProperties(prefix = "spring.datasource") 注解,将 yml 文件中的属性直接转换成 Bean 中的属性(前提是有 set 方法),而且属性的匹配很宽松,采用 Relaxed 绑定,以 firstName 举例(可匹配firstName、first-name、first_name、FIRST_NAME)。之后再在启动类中使用 @EnableConfigurationProperties(JavaConfig.class) 使之生效。

回到顶部

五、单元测试

    不同于 Spring 中的单元测试 —— 采用 @RunWith(SpringJUnit4ClassRunner.class) 和 @ContextConfiguration(locations = "classpath:applicationContext.xml"),SpringBoot 中使用 @RunWith(SpringRunner.class) 和 @SpringBootTest(classes = Example.class) :

复制代码

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Example.class)public class Test1 {    private static final Logger logger = LoggerFactory.getLogger(Test1.class);

    @Autowired    private DataSource dataSource;

    @Test    public void test1() {
        logger.info("@ConfigurationProperties 注解的实现效果:" + ((DruidDataSource) dataSource).getUrl());
    }

}

复制代码

原文出处:https://www.cnblogs.com/jmcui/p/9683354.html  

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP