springbootmavenplugin必须要有吗

JavaScript06

springbootmavenplugin必须要有吗,第1张

-Version: 1.0

Created-By: Maven Archiver 3.4.0

Build-Jdk-Spec: 11

Implementation-Title: springbootfirst

Implementation-Version: 0.0.1-SNAPSHOT

SpringBoot插件生成的jar包结构为

BOOT-INF/classes 中包含项目所有的class文件,BOOT-INF/lib 下包含项目依赖的第三方jar包,MANIFEST.MF文件内容为

Manifest-Version: 1.0

Created-By: Maven Archiver 3.4.0

Build-Jdk-Spec: 11

Implementation-Title: springbootfirst

Implementation-Version: 0.0.1-SNAPSHOT

Main-Class: org.springframework.boot.loader.JarLauncher

Start-Class: com.imooc.springbootfirst.SpringbootfirstApplication

Spring-Boot-Version: 2.1.6.RELEASE

Spring-Boot-Classes: BOOT-INF/classes/

Spring-Boot-Lib: BOOT-INF/lib/

插件是如何找到启动类的

描述文件中的Start-Class就是我们项目的启动类,我们可以查看插件源码来分析

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<version>2.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-loader</artifactId>

<version>2.2.1.RELEASE</version>

</dependency>

先引入插件的maven依赖

RepackageMojo就是repackage打包要执行的逻辑,核心类为Repackager

在插件创建MANIFEST.MF文件过程中,如果我们没有配置MainClass属性,就会通过MainClassFinder类来查找MainClass

private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication"

protected String findMainMethod(JarFile source) throws IOException {

return MainClassFinder.findSingleMainClass(source, this.layout.getClassesLocation(),

SPRING_BOOT_APPLICATION_CLASS_NAME)

}

在所有类中查找包含SpringBootApplication注解且包含main方法的类,并当做启动类,内部通过ASM字节码库来解析class文件得到类信息。

启动流程

java -jar springbootfirst-0.0.1-SNAPSHOT.jar

java启动jar包会找META-INF/MANIFEST.MF文件中的Main-Class来启动,SpringBoot插件最终生成的Main-Class为 org.springframework.boot.loader.JarLauncher类。

/**

* jar包类型的启动器

*

* @author Phillip Webb

* @author Andy Wilkinson

* @since 1.0.0

*/

public class JarLauncher extends ExecutableArchiveLauncher {

static final String BOOT_INF_CLASSES = "BOOT-INF/classes/"

static final String BOOT_INF_LIB = "BOOT-INF/lib/"

public JarLauncher() {

}

protected JarLauncher(Archive archive) {

super(archive)

}

@Override

protected boolean isNestedArchive(Archive.Entry entry) {

if (entry.isDirectory()) {

return entry.getName().equals(BOOT_INF_CLASSES)

}

return entry.getName().startsWith(BOOT_INF_LIB)

}

public static void main(String[] args) throws Exception {

new JarLauncher().launch(args)

}

}

最终运行的是MANIFEST.MF文件中Start-Class,值为com.imooc.springbootfirst.SpringbootfirstApplication,其实就是我们项目中配置的启动类。

/**

* 启动器

*

* @author Phillip Webb

* @author Dave Syer

* @since 1.0.0

*/

public abstract class Launcher {

/**

* 启动流程

*/

protected void launch(String[] args) throws Exception {

JarFile.registerUrlProtocolHandler()

//根据BOOT-INF/classes下的class文件和BOOT-INF/lib下的第三方jar包创建Archive

//创建的ClassLoader为LaunchedURLClassLoader类型

ClassLoader classLoader = createClassLoader(getClassPathArchives())

launch(args, getMainClass(), classLoader)

}

/**

* 创建新的LaunchedURLClassLoader,从多个URL中加载class

*/

protected ClassLoader createClassLoader(URL[] urls) throws Exception {

return new LaunchedURLClassLoader(urls, getClass().getClassLoader())

}

/**

* 将新的类加载器设置到线程上下文中,并启动应用程序

*/

protected void launch(String[] args, String mainClass, ClassLoader classLoader) throws Exception {

Thread.currentThread().setContextClassLoader(classLoader)

createMainMethodRunner(mainClass, args, classLoader).run()

}

/**

* 创建一个Main方法运行器来启动应用程序

*/

protected MainMethodRunner createMainMethodRunner(String mainClass, String[] args, ClassLoader classLoader) {

return new MainMethodRunner(mainClass, args)

}

}

创建新的ClassLoader类型LaunchedURLClassLoader,从BOOT-INF/classes下和BOOT-INF/lib下的所有jar包中加载class。加载我们整个项目的都是LaunchedURLClassLoader类加载器。

/**

* 一个执行Main方法的工具类

*

* @author Phillip Webb

* @author Andy Wilkinson

* @since 1.0.0

*/

public class MainMethodRunner {

private final String mainClassName

private final String[] args

/**

* Create a new {@link MainMethodRunner} instance.

* @param mainClass the main class

* @param args incoming arguments

*/

public MainMethodRunner(String mainClass, String[] args) {

this.mainClassName = mainClass

this.args = (args != null) ? args.clone() : null

}

public void run() throws Exception {

//使用线程上下文类加载器加载MainClass,就是我们项目中的SpringbootfirstApplication

Class<?>mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName)

//执行Main方法

Method mainMethod = mainClass.getDeclaredMethod("main", String[].class)

mainMethod.invoke(null, new Object[] { this.args })

}

}

参考

springboot 打包插件spring-boot-maven-plugin打包机制及内部结构分析

分类: spring

标签: spring, maven, java

好文要顶 关注我 收藏该文

strongmore

粉丝 - 9 关注 - 5

+加关注

00

« 上一篇: IDEA中对非Maven项目导出jar包

» 下一篇: java实现对图片打马赛克

posted @ 2021-11-04 18:50  strongmore  阅读(6395)  评论(0)  编辑  收藏  举报

刷新评论刷新页面返回顶部

登录后才能查看或发表评论,立即 登录 或者 逛逛 博客园首页

【推荐】阿里云新人特惠,爆款云服务器2核4G低至0.46元/天

编辑推荐:

· 一次 SQL 调优,聊一聊 SQLSERVER 数据页

· 终于弄明白了 RocketMQ 的存储模型

· 应届毕业生程序员在面试时如何做好自我介绍?

· Redis 网络模型究竟有多强

· 不规则图形背景排版高阶技巧 -- 酷炫的六边形网格背景图

阅读排行:

· 来自一位十年.net研发老人的吐血整理:.Net技术栈-网址导航

· 做算法的这一年——2022年个人年终总结

· .Net 7 团队把国内的龙芯确实当做一等公民和弃用的项目

· 我希望来年,更多是靠关系和模式挣钱——2022年我的总结与思考

· 平淡详和的一年——2022年个人总结与思考

昵称: strongmore

园龄: 3年7个月

粉丝: 9

关注: 5

+加关注

< 2023年1月 >

日 一 二 三 四 五 六

1 2 3 4 5 6 7

8 9 10 11 12 13 14

15 16 17 18 19 20 21

22 23 24 25 26 27 28

29 30 31 1 2 3 4

5 6 7 8 9 10 11

搜索

 找找看

 谷歌搜索

常用链接

我的随笔

我的评论

我的参与

最新评论

我的标签

最新随笔

1.单元测试框架之Junit使用及原理分析

2.Kotlin学习之反射

3.Kotlin学习之Kotlin和Java之间相互调用

4.Kotlin学习之函数

5.Kotlin学习之委托

6.Kotlin学习之面向对象

7.Kotlin学习之基本语法

8.SpringMVC整合Swagger简单使用及原理分析

9.SpringMVC源码分析之一个请求的处理

10.Spring整合Mqtt原理分析

我的标签

java(220)

算法(40)

数据结构(39)

spring(30)

设计模式(28)

python(11)

多线程(8)

踩坑(8)

linux(8)

kotlin(8)

更多

积分与排名

积分 - 174759

排名 - 6340

随笔分类

c语言(2)

html(2)

java(136)

js(4)

kotlin(7)

leetcode(11)

linux(8)

python学习之旅(8)

spring(28)

机器学习(1)

数据结构与算法(34)

网络(2)

随笔档案

2022年6月(6)

2022年5月(28)

2022年4月(12)

2022年3月(5)

2022年2月(1)

2021年11月(3)

2021年10月(6)

2021年9月(13)

2021年8月(21)

2021年7月(13)

2021年6月(9)

2021年5月(6)

2021年4月(11)

2021年3月(21)

2021年2月(5)

更多

阅读排行榜

1. java中文转拼音(12794)

2. java操作yaml文件(9029)

3. java实现图片压缩(7791)

4. jdk8升级jdk11踩坑记录(lombok版本不兼容)(7465)

5. IDEA版本和Maven版本不兼容的问题(6840)

评论排行榜

1. Lombok原理分析及简单实现(4)

2. java中BloomFilter(布隆过滤器)简单使用(3)

3. java中如何通过程序检测线程死锁(1)

4. Spring中表达式语言spring-expression简单使用(1)

5. 关于100个人随机给钱的模拟实验(1)

推荐排行榜

1. MurmurHash算法简单介绍(2)

2. java操作yaml文件(2)

3. java进行PDF和图片之间的相互转换(2)

4. JMX简单入门(2)

5. 浏览器的DNS解析过程分析(1)

最新评论

1. Re:Spring中表达式语言spring-expression简单使用

支持

--我叫城北徐公

2. Re:java中BloomFilter(布隆过滤器)简单使用

@strongmore 好的好的,感谢回复~~...

--言小蹊

3. Re:java中BloomFilter(布隆过滤器)简单使用

@言小蹊 在IDEA上...

--strongmore

4. Re:java中BloomFilter(布隆过滤器)简单使用

您好,请问您这是是如何查看内存使用情况的?您是在eclipse上运行的代码吗?

--言小蹊

5. Re:java实现一个短URL生成器

博主介绍的短链接生成核心代码的确挺实用的,短链接就是将长的网页址通过技术方法进行缩短为短串。其实短链接只有生成和跳转还不能满足实际业务需求,还需要考虑其使用场景,目前短链接使用场景主要是短信内带短链接...

--缩链

Copyright © 2023 strongmore

Powered by .NET 7.0 on Kubernetes

1. 前言

2. 打包原理

3. 插件是如何找到启动类的

4. 启动流程

5. 参考

可选链 操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。 ?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空( nullish ) ( null 或者 undefined ) 的情况下不会引起错误,该表达式短路返回值是 undefined 。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined 。

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出错误。

有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:

摘自: 可选链操作符

Tips:

Tips:

1、vue2中

2、vue3中,有vue.config.js 的 非vite 项目

3、vue3中,有 vite.config.js 的 vite 项目

4、让后台配合给一个接口,获取微信的config参数

比如node 后台 可参照 node 获取微信签名并使用jssdk

其它语言的随便搜搜都有~

Tips

5、使用开放标签

vue2 中

vue3 中

Tips

由于短信引流成本低,很多公司都使用这样的方式去吸引流量,核心是获取URL Scheme

可查阅 微信官方文档

太长不想看?

核心几点如下:

Tips

如果你这个模板只服务一个短信链接,完全可以写死跳转的url,但是你想搞成通用的,可以像我上面这样封装下,根据类型去不同的小程序。然后URL Scheme也可以向后台实时获取新的,确保这个中间页的链接是有效的。

由于不再支持永久有效,IOS也走中间页,在中间页动态获取有效的URL Scheme实现跳转

缺点:

这样后台要开发接口配合你来获取该链接,且你的h5地址如果很长,最好能生成短链,这样放在短信中不至于太长。

无公众号直接使用小程序身份开发网页并免鉴权跳转小程序?可以吗?

可以参考 官方文档