SpringBoot自动配置

本文详细介绍了SpringBoot自动配置的原理和使用,包括其优点、快速入门回顾、配置分析、Enable相关注解等内容。通过分析@SpringBootApplication注解,揭示了SpringBoot如何根据项目依赖自动配置Spring框架,以及如何自定义配置文件、加载外部配置、处理配置文件中的值。最后,探讨了自动配置的核心——@EnableAutoConfiguration的工作机制。
摘要由CSDN通过智能技术生成

SpringBoot自动配置

1. SpringBoot优缺点

  前面我们已经对SpringBoot有了简单的了解与使用。SpringBoot对于开发者来说使用非常方便,那我们先整理一下优缺点。
总结优点如下:
  1)使编码变简单:为基于Spring的开发提供更快的入门体验,轻松创建可以独立运行的Spring应用。
  2)使配置变简单:直接推荐的基础POM文件—starter来简化Apache Maven配置,尽可能的根据项目依赖来自动配置的Spring框架。
  3)使部署变简单:直接嵌入Tomcat或Jetty服务器,不需要再打包成WAR文件。
  4)使监控变简单:提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查等。
总结缺点如下:
  1)依赖太多,随便的一个SpringBoot应用都有好几十M。
  2)缺少服务的注册和发现等解决方案。
  3)缺少监控集成方案、安全管理方案。
  4)中文的文档和资料少且不够深入。
基于SpringBoot的特点,主要应用场景如下:
1)Spring能够应用的场景。
2)Java Web应用。
3)微服务。

2. 快速入门回顾

2.1 创建项目

IDEA创建一个SpringBoot项目,项目结构如下:
SpringBoot项目结构
我们发现,自动创建了一个类Application,我们称之为启动类。.mvn目录、mvnw与mvnw.cmd文件可以删掉;

2.2 环境搭建

  我们用Idea创建SpringBoot web项目,自动为我们搭建好了环境。我们查看POM文件,发现搭建SpringBoot环境,是采用继承的方式:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

  若想集成SpringBoot环境,还有第二种方式,即配置dependencyManagement,POM配置如下:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.8.RELEASE</version>
			<scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>
2.3 启动项目

  我们知道项目启动依靠的是启动器(启动类),这是创建项目时自动为我们创建的,只要运行其中的main方法,即启动项目。

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

  启动方式除了默认的调用SpringApplication的静态方法run之外,还可以通过SpringApplication实例调用run方法实现,代码如下:

@SpringBootApplication
public class App1 {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication();
        application.run(App1.class, args);
    }
}
@SpringBootApplication
public class App2 {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(App2.class);
        springApplication.run(args);
    }
}
2.4 初识@SpringBootApplication注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
	//...
}

我们发现该注解中包含了4个元注解与3个Spring注解:
1)4个元注解:

@Target:定义注解的作用目标 。
@Retention: 定义注解的保留策略 。
@Document:说明该注解将被包含在javadoc中。
@Inherited:说明子类可以继承父类中的该注解。

2)3个Spring的注解:

@ComponentScan:自动扫描包(扫描项目中标注为Spring组件的类,从而使标注controller、service、repository及component的bean都能正常注入到Spring容器并提供使用)。
@EnableAutoConfiguration:开启自动配置,后面作详细介绍
@SpringBootConfiguration:标注当前类作为配置类,作为配置类后我们就可以在该类中配置Bean了。

  @SpringBootConfiguration的作用,演示效果如下:在该类中配置一个bean,在项目启动中可以通过context对象获取到该实例,说明已经该bean成功被注入到Spring容器中了。

@SpringBootApplication
public class Application {

    @Bean
    public Runnable createRunnable() {
        return () -> {
            System.out.println("Creating runnable...");
        };
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        context.getBean(Runnable.class).run();
        context.close();
    }

}

3. SpringBoot配置分析

3.1 获取配置文件中的值
3.1.1 直接获取配置文件中变量的值

在配置文件application.properties中添加配置信息:

local.ip=192.168.198.132
local.port=8023
local.name=chavaer

根据key获取配置文件中的值,有两种方式,如下:
1)通过Environment对象的getProperty()方法获取;
2)通过@Value注解获取;
代码实现:

package com.chavaer.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class Config {

    @Autowired
    private Environment env;

    //方法3:通过@Value注解获取
    @Value("${local.name}")
    private String name;

    //方法4:通过@Value注解获取,自动进行类型转换
    @Value("${local.port}")
    private Integer port;

    public void getCfgValue() {
        //方法1:通过getProperty()方法获取
        String ip = env.getProperty("local.ip");

        //方法2:通过getProperty()方法获取,自动进行类型转换
        Integer localPort = env.getProperty("local.port", Integer.class);

        System.out.println("local.ip:" + ip);
        System.out.println("local.port:" + localPort);
        System.out.println("local.name:" + name);
        System.out.println("local.port:" + port);
    }
}
@SpringBootApplication
public class App {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =
                SpringApplication.run(App.class, args);
        context.getBean(Config.class).getCfgValue();
        context.close();
    }
}

控制台打印信息如下:
获取配置文件值结果

3.1.2 获取配置文件中引用变量的值

当配置文件中存在引用变量时,获取方式同上:

project=springboot
project.name=this is ${project}
@Component
public class Config {

    @Autowired
    private Environment env;

    public void getCfgValue() {
        String name = env.getProperty("project");
        String proName = env.getProperty("project.name");

        System.out.println("project:" + name);
        System.out.println("project.name:" + proName);
    }
}

获取结果如下:
获取引用变量结果

3.1.3 获取配置文件中不存在的键值对

  当给定Key在配置文件中不存在时,需要给定默认值,否则会报错。如我们获取Key为“tomcat.port”的值,我们并没有在配置文件中配置:

@Component
public class Config {

    @Autowired
    private Environment env;

    @Value("${tomcat.port}")
    private String tomcatPort;


    public void getCfgValue() {
        System.out.println("tomcat.port:" + tomcatPort);
    }
}

出现异常信息如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'config': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'tomcat.port' in value "${tomcat.port}"
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:380) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值