【SpringBoot2.x】--Spring Boot核心(原理以及代碼實現)

代碼實現github:github.com/Ccww-lx/Spr…

  SpringBoot做爲咱們平常開發的框架,咱們必須熟悉掌握SpringBoot基礎核心,包括SpringBoot運行原理、基礎配置、外部配置、日誌配置、Profile配置、核心註解等等,其中:html

SpringBoot運行原理:java

  • 入口類和@SpringBootApplication
  • Starter pom

核心註解:git

  • 註解解析
  • 自定義

基礎配置:github

  • banner配置
  • Spring Boot配置文件(properties、yaml)
  • xml文件配置

外部配置:web

  • 命令行參數配置
  • 常規屬性配置、類型安全的配置

日誌配置:redis

  • 支持Log4J、Log4J2以及Logback(默認)

Profile配置:spring

  • 不一樣環境對應不一樣配置:application-{profile}.properties

基礎配置

banner配置

在src/main/resources下新建一個banner.txt,banner.txt能夠經過網站生成字符自動生成。啓動閉關代碼以下:mongodb

@SpringBootApplication
public class BaseSpringBootApplication {

    public static void main(String[] args) {

        //關閉banner
        SpringApplication application = new SpringApplication(BaseSpringBootApplication.class);
        //application.setBannerMode(Banner.Mode.OFF);
        application.run();
        //使用fluent API修改
       /* new SpringApplicationBuilder(BaseSpringBootApplication.class)
                .bannerMode(Banner.Mode.OFF)
                .run();*/

    }
}
複製代碼

Spring Boot配置文件(properties、yaml)

可以使用配置文件application.properties或application.yml, 放置在src/main/resources目錄下的任何目錄下。以下圖所示:數據庫

xml文件配置

可以使用註解@ImportResource來加載xml配置,更加spring boot的靈活性。代碼以下:編程

//導入Spring的配置文件,讓配置文件裏面的內容生效
@ImportResource(locations = {"classpath:base.xml"})
@Configuration
public class LoadXmlFileConfiguration {
//加載base.xml文件下的bean到IOC容器中
}
複製代碼

外部配置

命令行參數配置

能夠直接在啓動時經過命令行進行配置,以下:

java -jar xxx.jar --server.port=8888
複製代碼

更多詳細參數使用能夠查看。

常規屬性配置、類型安全的配置

  經過@Value注入值,只需在properties或者yaml文件中定義屬性, 直接使用@Value注入便可,也經過@ConfigurationProperties將properties或者yaml屬性和一個Bean及其屬性關聯, 從而實現類型安全的配置。代碼以下所示:

//經過@ConfigurationProperties加載properties文件屬性
//可以使用perfix前綴指定加載properties文件屬性,經過location加載指定文件
@ConfigurationProperties(prefix = "project")
@Configuration
public class AutoConfigurationProperties {
    @Value("${project.name}")
    private String projectName;
    @Value("project.author")
    private String projectAuthor;

    public String getServerInfo() {
        System.out.println("projectName:" + projectName + "projectAuthor:" + projectAuthor);
        return "projectName:" + projectName  +" ----" + "projectAuthor:" + projectAuthor;
    }
}
複製代碼

日誌配置

Spring Boot默認使用Logback做爲日誌框架,也支持Java Util Logging、 Log4J、 Log4J2。

log從高到低級別:

  • OFF Level:最高等級的,用於關閉全部日誌記錄
  • FATAL level:指出每一個嚴重的錯誤事件將會致使應用程序的退出
  • ERROR level:指出雖然發生錯誤事件,但仍然不影響系統的繼續運行
  • WARN level:明會出現潛在錯誤的情形
  • INFO level:應用程序的運行過程
  • DEBUG Level:調試應用級別
  • TRACE :記錄事件消息
  • ALL:是最低等級的,用於打開全部日誌記錄

日誌配置以下:

<?xml version="1****.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<Properties>
		<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
		<Property name="LOG_LEVEL_PATTERN">%5p</Property>
		<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
		<Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
		<Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
	</Properties>
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT" follow="true">
			<PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
		</Console>
	</Appenders>
	<Loggers>
		<Logger name="com.cn.ccww.*" level="info" />
		<Root level="info">
			<AppenderRef ref="Console" />
		</Root>
	</Loggers>
</Configuration>
複製代碼

Profile配置

不一樣環境對應不一樣配置:application-{profile}.properties,並經過在application.properties中設置 spring.profiles.active=prod來指定活動的Profile。以下圖所示:

SpringBoot運行原理

入口類和@SpringBootApplication

  一般定義一個XXXApplication的類並使用@SpringBootApplication註解做爲啓動類, 入口類裏有一個main方法,並使用SpringApplication.run( XXXApplication.class, args) , 啓動Spring Boot應用項目。

  @SpringBootApplication是Spring Boot的核心註解, 它是一 個組合註解,它的核心功能是由@EnableAutoConfiguration註解提供,並由@Import註解導入EnableAutoConfigurationImportSelector類實現自動配置。

@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 {
    ....
}
複製代碼

詳細@SpringBootApplication源碼能夠查看文章簡明易理解的@SpringBootApplication註解源碼分析】

Starter pom

  Spring Boot爲咱們提供了簡化企業級開發絕大多數場景的starter pom, 只要使用了應用場景所須要的starter pom, 相關的 技術配置將會消除, 就能夠獲得Spring Boot爲咱們提供的自動配置的Bean。

常見starter:

名稱 描述
spring-boot-starter Spring Boot核心starter,包含自動配置、日誌、yaml配置文件支持
spring-boot-starter-activemq 爲JMS使用Apache ActiveMQ
spring-boot-starter-amqp 使用Spring AMQP、Rabbit MQ
spring-boot-starter-aop 經過Spring AOP、AspectJ面向切面編程
spring-boot-starter-cache 使用 Spring caching緩存支持
spring-boot-starter-data-cassandra 使用Cassandra分佈式數據庫、Spring Data Cassandra
spring-boot-starter-data-elasticsearch 使用Elasticsearch、analytics engine、Spring Data Elasticsearch
spring-boot-starter-data-jdbc 經過 Tomcat JDBC 鏈接池使用JDBC
spring-boot-starter-data-jpa 經過 Hibernate 使用 Spring Data JPA (Spring-data-jpa依賴於Hibernate)
spring-boot-starter-data-mongodb 使用 MongoDB 文件存儲數據庫、Spring Data MongoDB
spring-boot-starter-data-neo4j 使用Neo4j圖形數據庫、Spring Data Neo4j
spring-boot-starter-data-redis 經過Spring Data Redis 、Jedis client使用Redis鍵值存儲數據庫
spring-boot-starter-data-rest 使用Spring Data REST 以 REST 方式暴露 Spring Data repositories
spring-boot-starter-data-solr 經過 Spring Data Solr 使用 Apache Solr搜索引擎
spring-boot-starter-freemarker 使MVC Web applications 支持 FreeMarker,相似JSP
spring-boot-starter-groovy-templates 使MVC Web applications 支持Groovy Templates
spring-boot-starter-integration 使用Spring Integration,Spring Integration是Spring框架建立的一個API,面向企業應用集成(EAI)
spring-boot-starter-json 使用Json讀寫
spring-boot-starter-mail 使用Java Mail、Spring email發送支持
spring-boot-starter-oauth2-client 使用Spring Security’s OAuth2或者OpenID鏈接客戶端
spring-boot-starter-quartz 使用Quartz scheduler
spring-boot-starter-security 使用 Spring Security安全框架
spring-boot-starter-test 測試 Spring Boot applications包含JUnit、 Hamcrest、Mockito
spring-boot-starter-thymeleaf 使MVC Web applications 支持Thymeleaf,相似JSP
spring-boot-starter-validation 經過Hibernate Validator使用 Java Bean Validation,Bean Validation 是一個數據驗證的規範;Hibernate Validator是一個數據驗證框架
spring-boot-starter-web 構建Web,包含RESTful風格框架SpringMVC和默認的嵌入式容器Tomcat
spring-boot-starter-webflux 支持使用Spring Framework’s Reactive Web構建WebFlux applications
spring-boot-starter-websocket 使用Spring WebSocket構建 WebSocket 應用

更多詳細strater能夠查看官方文檔13.5 Starters

自定義starter

  自定義Starter能夠查看【SpringBoot】--自定義starter(原理以及代碼實現)】

核心註解

  核心註解的條件註解在org.springframwork.boot.autoconfigure.condition包下,其都由元註解@Conditional組合而成。更多的註解詳情可查看文章【推薦收藏系列:Spring boot 2.x註解Annotation大全(持續更新....)】

註解 解析
@ConditionalOnBean 當容器裏有指定的Bean的條件下。
@ConditionalOnClass 當類路徑下有指定的類的條件下。
@ConditionalOnExpression 基於SpEL表達式做爲判斷條件。
@ConditionalOnJava 基於JVM版本做爲判斷條件。
@ConditionalOnJndi 在JNDI存在的條件下查找指定的位置。
@ConditionalOnMissingBean 當容器裏沒有指定Bean的狀況下。
@ConditionalOnMissingClass 當類路徑下沒有指定的類的條件下。
@ConditionalOnNotWebApplication 當前項目不是Web項目的條件下。
@ConditionalOnProperty 指定的屬性是否有指定的值。
@ConditionalOnResource 類路徑是否有指定的值。
@ConditionalOnSingleCandidate 當指定Bean在容器中只有一個, 或者雖然有多個可是指定首選的Bean。
@ConditionalOnWebApplication 當前項目是Web項目的條件下

源碼分析:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnMissingBean {
    .....
}
複製代碼

其中,@Conditional的OnBeanCondition類爲@ConditionalOnMissingBean的實現,可自定義,詳情查看下節。

自定義conditional實現類:

實現一個是否windows系統條件的conditional實現類,代碼以下:

//判斷是否windows系統
public class WindowsCondition implements Condition {

    private final static String WINDOWS="Windows";

    /**
     * ConditionContext:判斷條件能使用的上下文(環境)
     * AnnotatedTypeMetadata:註釋信息
     */
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //獲取當前環境變量
        Environment environment=conditionContext.getEnvironment();
        //獲取bean註冊器
        BeanDefinitionRegistry registry = conditionContext.getRegistry();
        //能獲取到ioc使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //獲取環境變量中操做系統
        String property = environment.getProperty("os.name");
        //判斷操做系統是否爲windows
        if(property.contains(WINDOWS)){
            //判斷是否存在baseWindowsSevice類,不存在則進行bean註冊
            boolean isWindowsSevice = registry.containsBeanDefinition("baseWindowsSevice");
            if(!isWindowsSevice){
                //指定Bean定義信息;(Bean的類型,Bean的一系列信息)
                RootBeanDefinition beanDefinition = new RootBeanDefinition(BaseWindowsService.class);
                //註冊一個Bean,指定bean名
                registry.registerBeanDefinition("baseWindowsSevice", beanDefinition);
                BaseWindowsService windowsSevice = (BaseWindowsService)beanFactory.getBean("baseWindowsSevice");
                windowsSevice.addServiceName("ccww---baseWindowsSevice");
            }
            return true;
        }
        return false;
    }
}
複製代碼

最後可關注公衆號,一塊兒學習,天天會分享乾貨,還有學習視頻領取!

相關文章
相關標籤/搜索