在eclipse中创建一个maven工程
在eclipse中创建一个maven工程,创建完成后的布局:
生成的pom.xml文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thb</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
编辑pom.xml文件,增加parent元素:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thb</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
</parent>
</project>
现在到cmd窗口,切换到maven工程的根目录下面,执行mvn package
命令,就可以正常生成jar包,尽管里边没有什么内容:
增加类路径依赖
大多数Spring Boot应用在pom.xml文件中的parent
部分使用spring-boot-starter-parent
。spring-boot-starter-parent
是一个特别的starter,它提供了有用的maven默认值,也提供了一个dependency-management
段落,因此你可以省略依赖项的版本。
在增加依赖前,我们先用命令mvn dependency:tree
打印当前的项目依赖:
从输出可以看到,spring-boot-starter-parent
本身并没有提供依赖。
因为我们要开发一个web应用,因此,编辑pom.xml文件,在parent段落的后面,增加对spring-boot-starter-web
的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
此时,再运行mvn dependency:tree
,观察项目的依赖:
从输出可以看出,此时包含了许多的依赖,其中就包含tomcat web服务器和Spring Boot本身。
编写代码
创建一个MyApplication类,代码如下:
package myproject.com.thb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MyApplication {
@RequestMapping("/")
String home() {
return "Hello World";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@RestController和@RequestMapping注解
- @RestController是一个原型注解,指出被注解的类是一个web控制器,因此当spring处理进来的web请求的时候会考虑它。
- @RequestMapping注解提供了路由信息。它告诉spring将以
/
为路径的HTTP请求映射到home方法。@RestController注解告诉spring直接将方法返回的字符串提供给调用者。 - 备注:@RestController和@RequestMapping注解是Spring MVC的注解,它们不是Spring Boot特有的。
@SpringBootApplication注解
- @SpringBootApplication是一个元注解,它结合了@SpringBootConfiguration,
@EnableAutoConfiguration 和 @ComponentScan。 - 其中@EnableAutoConfiguration告诉Spring Boot,基于你已经增加的jar包的依赖,猜测你想怎么样配置spring。因为
spring-boot-starter-web
增加了Tomcat和Spring MVC,因此自动配置假设你正在开发一个web应用,并且相应地设置Spring。 - Starters和Auto-configuration:自动配置被设计得可以和“Starters协作良好,但这两个概念没有直接联系。你可以在starters之外随意选择jar依赖,Spring Boot仍然尽力自动配置你的应用。
main方法
main方法是一个标准的方法,它遵循应用程序入口的Java约定。通过调用run方法委托给Spring Boot的SpringApplication类,SpringApplication引导我们的应用、启动Spring,Spring又启动自动配置的Tomcat web服务器。
我们需要将MyApplication.class作为一个参数传给run方法,告诉SpringApplication它是主要的Spring组件。args数组也传递给run方法,以便暴露命令行参数。
运行样例
用maven运行
至此,你的应用应该可以运行了。因为你用了spring-boot-starter-parent
POM,所以有一个有用的run
goal可以启动应用。
到cmd窗口,切换到maven工程的根目录下,运行mvn spring-boot:run
来启动应用,看到如下输出信息:
在浏览器中输入localhost:8080
,看到如下输出:
要正常退出应用程序,按ctrl-c。
生成一个可执行的Jar
用maven生成
为了生成一个可执行的jar,将依赖也打包进去,我们需要添加spring-boot-maven-plugin
到我们的pom.xml。为此,在dependencies
小节的后面增加如下片段:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
现在完整的pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thb</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意:spring-boot-starter-parent
POM包含<executions>
配置,以绑定repackage
goal。如果你没有使用这个父POM,那么需要你自己声明这个配置。
现在到cmd窗口,运行mvn package
,输出信息如下:
到target目录下,可以看到生成的myproject-0.0.1-SNAPSHOT.jar
,文件大小18MB多。另外,还有一个文件myproject-0.0.1-SNAPSHOT.jar.original
,文件大小3KB,这个是在Spring Boot重新打包之前,maven生成的原始jar包:
将myproject-0.0.1-SNAPSHOT.jar解压,可以看到里边包含的文件:
D:.
├─BOOT-INF
│ │ classpath.idx
│ │ layers.idx
│ │
│ ├─classes
│ │ └─myproject
│ │ └─com
│ │ └─thb
│ │ MyApplication.class
│ │
│ └─lib
│ jackson-annotations-2.15.3.jar
│ jackson-core-2.15.3.jar
│ jackson-databind-2.15.3.jar
│ jackson-datatype-jdk8-2.15.3.jar
│ jackson-datatype-jsr310-2.15.3.jar
│ jackson-module-parameter-names-2.15.3.jar
│ jakarta.annotation-api-2.1.1.jar
│ jul-to-slf4j-2.0.9.jar
│ log4j-api-2.21.1.jar
│ log4j-to-slf4j-2.21.1.jar
│ logback-classic-1.4.14.jar
│ logback-core-1.4.14.jar
│ micrometer-commons-1.12.1.jar
│ micrometer-observation-1.12.1.jar
│ slf4j-api-2.0.9.jar
│ snakeyaml-2.2.jar
│ spring-aop-6.1.2.jar
│ spring-beans-6.1.2.jar
│ spring-boot-3.2.1.jar
│ spring-boot-autoconfigure-3.2.1.jar
│ spring-boot-jarmode-layertools-3.2.1.jar
│ spring-context-6.1.2.jar
│ spring-core-6.1.2.jar
│ spring-expression-6.1.2.jar
│ spring-jcl-6.1.2.jar
│ spring-web-6.1.2.jar
│ spring-webmvc-6.1.2.jar
│ tomcat-embed-core-10.1.17.jar
│ tomcat-embed-el-10.1.17.jar
│ tomcat-embed-websocket-10.1.17.jar
│
├─META-INF
│ │ MANIFEST.MF
│ │
│ ├─maven
│ │ └─com.thb
│ │ └─myproject
│ │ pom.properties
│ │ pom.xml
│ │
│ └─services
│ java.nio.file.spi.FileSystemProvider
│
└─org
└─springframework
└─boot
└─loader
├─jar
│ ManifestInfo.class
│ MetaInfVersionsInfo.class
│ NestedJarFile$JarEntriesEnumeration.class
│ NestedJarFile$JarEntryInflaterInputStream.class
│ NestedJarFile$JarEntryInputStream.class
│ NestedJarFile$NestedJarEntry.class
│ NestedJarFile$RawZipDataInputStream.class
│ NestedJarFile$ZipContentEntriesSpliterator.class
│ NestedJarFile.class
│ NestedJarFileResources.class
│ SecurityInfo.class
│ ZipInflaterInputStream.class
│
├─jarmode
│ JarMode.class
│
├─launch
│ Archive$Entry.class
│ Archive.class
│ ClassPathIndexFile.class
│ ExecutableArchiveLauncher.class
│ ExplodedArchive$FileArchiveEntry.class
│ ExplodedArchive.class
│ JarFileArchive$JarArchiveEntry.class
│ JarFileArchive.class
│ JarLauncher.class
│ JarModeRunner.class
│ LaunchedClassLoader$DefinePackageCallType.class
│ LaunchedClassLoader.class
│ Launcher.class
│ PropertiesLauncher$Instantiator$Using.class
│ PropertiesLauncher$Instantiator.class
│ PropertiesLauncher.class
│ SystemPropertyUtils.class
│ WarLauncher.class
│
├─log
│ DebugLogger$DisabledDebugLogger.class
│ DebugLogger$SystemErrDebugLogger.class
│ DebugLogger.class
│
├─net
│ ├─protocol
│ │ │ Handlers.class
│ │ │
│ │ ├─jar
│ │ │ Canonicalizer.class
│ │ │ Handler.class
│ │ │ JarFileUrlKey.class
│ │ │ JarUrl.class
│ │ │ JarUrlClassLoader$OptimizedEnumeration.class
│ │ │ JarUrlClassLoader.class
│ │ │ JarUrlConnection$ConnectionInputStream.class
│ │ │ JarUrlConnection$EmptyUrlStreamHandler.class
│ │ │ JarUrlConnection.class
│ │ │ LazyDelegatingInputStream.class
│ │ │ Optimizations.class
│ │ │ UrlJarEntry.class
│ │ │ UrlJarFile.class
│ │ │ UrlJarFileFactory.class
│ │ │ UrlJarFiles$Cache.class
│ │ │ UrlJarFiles.class
│ │ │ UrlJarManifest$ManifestSupplier.class
│ │ │ UrlJarManifest.class
│ │ │ UrlNestedJarFile.class
│ │ │
│ │ └─nested
│ │ Handler.class
│ │ NestedLocation.class
│ │ NestedUrlConnection$ConnectionInputStream.class
│ │ NestedUrlConnection.class
│ │ NestedUrlConnectionResources.class
│ │
│ └─util
│ UrlDecoder.class
│
├─nio
│ └─file
│ NestedByteChannel$Resources.class
│ NestedByteChannel.class
│ NestedFileStore.class
│ NestedFileSystem.class
│ NestedFileSystemProvider.class
│ NestedPath.class
│
├─ref
│ Cleaner.class
│ DefaultCleaner.class
│
└─zip
ByteArrayDataBlock.class
CloseableDataBlock.class
DataBlock.class
DataBlockInputStream.class
FileChannelDataBlock$ManagedFileChannel.class
FileChannelDataBlock$Tracker.class
FileChannelDataBlock.class
NameOffsetLookups.class
VirtualDataBlock.class
VirtualZipDataBlock$DataPart.class
VirtualZipDataBlock.class
Zip64EndOfCentralDirectoryLocator.class
Zip64EndOfCentralDirectoryRecord.class
ZipCentralDirectoryFileHeaderRecord.class
ZipContent$Entry.class
ZipContent$Loader.class
ZipContent$Source.class
ZipContent.class
ZipDataDescriptorRecord.class
ZipEndOfCentralDirectoryRecord$Located.class
ZipEndOfCentralDirectoryRecord.class
ZipLocalFileHeaderRecord.class
ZipString$CompareType.class
ZipString.class
要运行这个应用,可以执行命令java -jar target/myproject-0.0.1-SNAPSHOT.jar
:
要正常退出应用,按ctrl-c
。