SpringBoot從零單排 ------初級入門篇

程式設計師共同成長發表於2019-02-20

    有人說SSM已死,未來是SpringBoot和SpringCloud的天下,這個觀點可能有點極端,但不可否認的是已經越來越多的公司開始使用SpringBoot。所以我將平時學習SpringBoot的內容做個記錄,查漏補缺吧

建立SpringBoot專案

可以透過官方提供的Spring initializer工具來初始化springboot,同時IntelliJ IDEA 也整合了這個工具。因此可以根據個人需求選擇不同的建立方式

1、官方工具Spring initializer

網址 :

SpringBoot從零單排 ------初級入門篇

下載下的壓縮包進行解壓匯入到編輯器中即可。

2、Idea建立專案

New -> Project - > spring initializer -> 選擇SDK->填寫Group& Artifact->next->選擇所需jar的依賴(也可暫時勾選)->next->修改專案名->finish

建立成功之後的目錄

SpringBoot從零單排 ------初級入門篇

啟動專案

啟動springboot我們只需要執行上圖中的ManApplication中的main方法就可以了。

package com.objectman.springboot_study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootStudyApplication {

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

}

這個啟動類可以分為兩部分 1、@SpringBootApplication 2、SpringApplication.run

SpringBootApplication

檢視原始碼我們發現@SpringBootApplication是一個複合註解,主要包括了
@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

@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 {

}
@SpringBootConfiguration

其實原始碼中的註釋已經描述了這個註解的作用了

/**
* Indicates that a class provides Spring Boot application
* {@link Configuration @Configuration}. Can be used as an alternative to the Spring's
* standard {@code @Configuration} annotation so that configuration can be found
* automatically (for example in tests).
* <p>
* Application should only ever include <em>one</em> {@code @SpringBootConfiguration} and
* most idiomatic Spring Boot applications will inherit it from
* {@code @SpringBootApplication}.
*
* @author Phillip Webb
* @since 1.4.0
*/

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

Can be used as an alternative to the Spring's standard {@code @Configuration} annotation so that configuration can be found 主要意思是可以替代Spring的@Configuration註解。作用是將當前類中用@Bean註解標註的方法實力注入到Spring容器中,例項名就是方法名。
寫個程式碼,舉個例子

定義一個配置類,

import com.objectman.springboot_study.User;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootConfiguration
public class Configuration_Test {

   public Configuration_Test() {
       System.out.println("=====>>>>> Configuration_Test 容器啟動初始化");
   }

   @Bean
   public User createUser() {
       User user = new User();
       user.setUserName("Object Man");
       user.setAge(18);
       return user;
   }
}

在main方法中可以直接獲取bean。

@SpringBootApplication
public class SpringbootStudyApplication {

   public static void main(String[] args) {
       ConfigurableApplicationContext context = SpringApplication.run(SpringbootStudyApplication.class, args);
       User user = (User) context.getBean("createUser");
       System.out.println("使用者姓名為:" + user.getUserName() + ",今年" + user.getAge() + "歲了");
   }
}

啟動專案控制後臺輸出如下

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '
_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.1.RELEASE)

2019-01-05 20:25:18.761  INFO 71172 --- [           main] c.o.s.SpringbootStudyApplication         : Starting SpringbootStudyApplication on MicroWin10-1123 with PID 71172 (C:\Users\Administrator\IdeaProjects\springboot_study\target\classes started by Administrator in C:\Users\Administrator\IdeaProjects\springboot_study)
2019-01-05 20:25:18.789  INFO 71172 --- [           main] c.o.s.SpringbootStudyApplication         : No active profile set, falling back to default profiles: default
2019-01-05 20:25:19.787  INFO 71172 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-01-05 20:25:19.809  INFO 71172 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-01-05 20:25:19.809  INFO 71172 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/9.0.13
2019-01-05 20:25:19.816  INFO 71172 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [E:\JDK\jdk1.8.0_131\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;E:\JDK\jdk1.8.0_131\bin;E:\JDK\jdk1.8.0_131\jre\bin;C:\WINDOWS\System32\OpenSSH\;E:\apache-maven-3.5.4\bin;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;E:\program\MySql\mysql-8.0.13-winx64\bin;E:\program\node\;C:\Program Files\Git\cmd;E:\Python\Python_Controller\Scripts\;E:\Python\Python_Controller\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;.]
2019-01-05 20:25:19.900  INFO 71172 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-01-05 20:25:19.900  INFO 71172 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1001 ms
=====>>>>> Configuration_Test 容器啟動初始化
2019-01-05 20:25:20.124  INFO 71172 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService '
applicationTaskExecutor'
2019-01-05 20:25:20.300  INFO 71172 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '
'
2019-01-05 20:25:20.304  INFO 71172 --- [           main] c.o.s.SpringbootStudyApplication         : Started SpringbootStudyApplication in 1.945 seconds (JVM running for 2.714)
使用者姓名為:Object Man,今年18歲了

SpringBoot的核心理念約定優於配置,因此透過註解的形式取代了xml配置檔案,減少了工作量,也使程式碼變得簡潔。

@EnableAutoConfiguration

還是老規矩先看原始碼

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
   String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
   Class<?>[] exclude() default {};
   String[] excludeName() default {};
}

發現有個Import匯入了AutoConfigurationImportSelector類。那麼這個類是幹嘛的呢?檢視原始碼我們發現有個selectImports方法

public String[] selectImports(AnnotationMetadata annotationMetadata) {
       if (!isEnabled(annotationMetadata)) {
           return NO_IMPORTS;
       }
       //AutoConfigurationMetadataLoader是springboot autoconfigure載入AutoConfigurationMetadata的內部工具類
       AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
               .loadMetadata(this.beanClassLoader);
       AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
               autoConfigurationMetadata, annotationMetadata);
       return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
   }

loadMetadata的實現程式碼和相關程式碼如下:

//定義一個路徑
   protected static final String PATH = "META-INF/"
           + "spring-autoconfigure-metadata.properties";

   public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
       return loadMetadata(classLoader, PATH);
   }

   static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
       try {
           //找到自動配置的屬性檔案
           Enumeration<URL> urls = (classLoader != null) ? classLoader.getResources(path)
                   : ClassLoader.getSystemResources(path);
           //建立一個properties物件,將所有配置檔案載入到properties物件中
           Properties properties = new Properties();
           while (urls.hasMoreElements()) {
               properties.putAll(PropertiesLoaderUtils
                       .loadProperties(new UrlResource(urls.nextElement())));
           }
           return loadMetadata(properties);
       }
       catch (IOException ex) {
           throw new IllegalArgumentException(
                   "Unable to load @ConditionalOnClass location [" + path + "]", ex);
       }
   }

PATH路徑下被自動配置的類有

SpringBoot從零單排 ------初級入門篇

結論:EnableAutoConfiguration會將SpringBoot鎖需要的將配置載入到容器中。

@ComponentScan

可以把它理解為一個掃描器,一個專案中可能會有好多個控制器,我們就是透過ComponentScan去發現指定路徑下的@Controller(@RestController)、@Service、@Repository 、@Component並將他們裝入bean容器中。
他有如下幾個屬性

public enum FilterType {

  ANNOTATION, //按照註解過濾

  ASSIGNABLE_TYPE, //按照給定的型別過濾

  ASPECTJ, //使用ASPECTJ表示式

  REGEX, //透過正則

  CUSTOM //自定義規則

}

SpringApplication.run

該過程首先建立了一個SpringApplication物件例項,然後完某些例項的初始化。之後呼叫run方法。具體詳情可以參考原始碼和下圖

SpringBoot從零單排 ------初級入門篇

HelloWorld

新增依賴

pom檔案中有個parent標籤

<parent>
       <!-- 一個非常牛x的依賴,使用之後後面常用的依賴包可以不用寫version了 -->
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.1.1.RELEASE</version>
</parent>

這是SpringBoot的一個父級依賴,使用之後相關依賴的時候可以不用填寫版本、預設和父級依賴的版本一樣。然後我們需要在dependencies標籤中新增web依賴模組

<!-- WEB依賴包 -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

編寫Controller

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @RestController = @Controller + @ResponseBody
*
*/

@RestController
public class HelloWorldController {
   /**
    * RequestMapping 將Http請求對映到方法上
    */

   @RequestMapping("/")
   public String HelloWorld() {
       return "Hello World";
   }
}

然後啟動專案瀏覽器訪問: 就可以看到瀏覽器輸出"Hello World"

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562041/viewspace-2636507/,如需轉載,請註明出處,否則將追究法律責任。

相關文章