有人说 SSM 已死, 未来是 SpringBoot 和 SpringCloud 的天下, 这个观点可能有点极端, 但不可否认的是已经越来越多的公司开始使用 SpringBoot. 所以我将平时学习 SpringBoot 的内容做个记录, 查漏补缺吧
1, 创建 SpringBoot 项目
可以通过官方提供的 Spring initializer 工具来初始化 springboot, 同时 IntelliJ IDEA 也集成了这个工具. 因此可以根据个人需求选择不同的创建方式
1, 官方工具 Spring initializer
网址 :https://start.spring.io
下载下的压缩包进行解压导入到编辑器中即可.
2,Idea 创建项目
New -> Project -> spring initializer -> 选择 SDK->填写 Group& Artifact->next->选择所需 jar 的依赖 (也可暂时勾选)->next-> 修改项目名 ->finish
创建成功之后的目录
3, 启动项目
启动 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 路径下被自动配置的类有
结论: EnableAutoConfiguration 会将 SpringBoot 锁需要的将配置加载到容器中.
@ComponentScan
可以把它理解为一个扫描器, 一个项目中可能会有好多个控制器, 我们就是通过 ComponentScan 去发现指定路径下的 @Controller(@RestController),@Service,@Repository ,@Component 并将他们装入 bean 容器中.
他有如下几个属性
- public enum FilterType {
- ANNOTATION, // 按照注解过滤
- ASSIGNABLE_TYPE, // 按照给定的类型过滤
- ASPECTJ, // 使用 ASPECTJ 表达式
- REGEX, // 通过正则
- CUSTOM // 自定义规则
- }
- SpringApplication.run
该过程首先创建了一个 SpringApplication 对象实例, 然后完某些实例的初始化. 之后调用 run 方法. 具体详情可以参考源码和下图
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";
- }
- }
然后启动项目浏览器访问: http://localhost:8080/ 就可以看到浏览器输出 "Hello World"
来源: https://www.cnblogs.com/wyl-0120/p/10308374.html