当前位置: 代码网 > it编程>编程语言>Java > SpringBoot的pom文件、容器、组件使用及说明

SpringBoot的pom文件、容器、组件使用及说明

2025年11月14日 Java 我要评论
一、pom文件、配置文件1、pom文件<?xml version="1.0" encoding="utf-8"?><project xmlns="http://maven.apach

一、pom文件、配置文件

1、pom文件

<?xml version="1.0" encoding="utf-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <!-- pom模型版本 -->
    <modelversion>4.0.0</modelversion>
    
    <!-- 项目信息 -->
    <groupid>demo</groupid><!-- 项目唯一标识 -->
    <artifactid>springboot</artifactid><!-- 项目名 -->
    <version>0.0.1-snapshot</version><!-- 版本 -->
    <packaging>jar</packaging><!-- 打包方式 (pom,war,jar) -->
 
    <name>springboot</name><!-- 项目的名称, maven 产生的文档用 -->
    <description>demo project for spring boot</description><!-- 项目的描述, maven 产生的文档用 -->
 
    <!-- 父级项目 -->
	<parent> 
        <artifactid>spring-boot-starter-parent</artifactid>  <!-- 被继承的父项目的构件标识符 --> 
        <groupid>org.springframework.boot</groupid>  <!-- 被继承的父项目的全球唯一标识符 -->
        <version>1.5.7.release</version>  <!-- 被继承的父项目的版本 --> 
        <!-- 父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。
             maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativepath位置),
             然后在本地仓库,最后在远程仓库寻找父项目的pom。 --> 
        <relativepath/> <!-- lookup parent from repository -->
    </parent> 
	
	<!-- 模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 --> 
    <modules> 
        <!-- 子项目相对路径 --> 
        <module></module> 
    </modules> 
	
    <!-- 属性设置 -->
    <properties>
        <project.build.sourceencoding>utf-8</project.build.sourceencoding><!-- 编译字符编码为utf-8 -->
        <project.reporting.outputencoding>utf-8</project.reporting.outputencoding><!-- 输出字符编码为utf-8  -->
        <java.version>1.8</java.version><!-- jdk版本 -->
    </properties>
    
    <!-- 依赖关系 -->
    <dependencies>
        <!-- 测试 -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
        <!-- mysql(数据库) -->
        <dependency>
            <groupid>mysql</groupid>
            <artifactid>mysql-connector-java</artifactid>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <!-- 编译 -->
    <build>
        <!-- 插件 -->
        <plugins>
            <!-- maven插件 -->
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>
</project>

2、配置文件

springboot 支持以下几种类型的配置文件:

  • application.properties:基于属性键值对的配置文件,使用简单的 key=value 格式,可读性较高。
  • application.yml:基于 yaml 格式的配置文件,使用缩进和冒号表示属性的层次结构,可读性更好。
  • application.yaml:与 application.yml 相同,只是文件扩展名不同。

优先级从高到低

properties -> yml -> yaml

bootstrap.yml配置文件

在 springcloud 的项目中常用到 bootstrap.yml配置文件,用于应用程序上下文的引导阶段,在 application.yml 之前加载。

二、spring的流程

1、spring的启动

2、spring中bean的生命周期

(1).spring对bean进行实例化;

(2).spring将值和bean的引用注入到bean对应的属性中;

(3).bean实现了beannameaware接口,spring将bean的id传递给setbean-name()方法;

(4).bean实现了beanfactoryaware接口,spring将调用setbeanfactory()方法,将beanfactory容器实例传入;

(5).bean实现了applicationcontextaware接口,spring将调用setapplicationcontext()方法,将bean所在的应用上下文的引用传入进来;

(6).bean实现了beanpostprocessor接口,spring将调用它们的postprocessbeforeinitialization()方法;

(7).bean实现了initializingbean接口,spring将调用它们的after-propertiesset()方法。类似地,

(8).bean使用initmethod声明了初始化方法,该方法也会被调用;

(9).bean实现了beanpostprocessor接口,spring将调用它们的post-processafterinitialization()方法;

(10).bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

(11).bean实现了disposablebean接口,spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

三、内置容器

springboot提供了四种web容器,分别为tomcat,jetty,undertow,netty。

1、tomcat(默认)

tomcat在8.0之前默认采⽤的i/o⽅式为bio,之后改为nio,适合处理少数非常繁忙的链接。

1.tomcat组成、架构

(1)tomcat中只有一个server,一个server可以有多个service,一个service可以有多个 connector(链接) 和一个 container(容器);

(2)server 掌管着整个tomcat的生死大权;

(4)service 是对外提供服务的;

(5)connector 用于接受请求并将请求封装成request和response来具体处理;

(6)container 用于封装和管理servlet,以及具体处理request请求;

2.tomcat性能调优

  • nameprefix: 线程前缀
  • maxthreads: 最大线程数,默认设置 200,一般建议在 500 ~ 1000,根据硬件设施和业务来判断
  • minsparethreads: 核心线程数,默认设置 25
  • prestartminsparethreads: 在 tomcat 初始化的时候就初始化核心线程
  • maxqueuesize: 最大的等待队列数,超过则拒绝请求 ,默认 integer.max_value
  • maxidletime: 线程空闲时间,超过该时间,线程会被销毁,单位毫秒。

3.tomcat热加载实

调用 context 容器的 reload 方法,先stop context容器,再start context容器。具体的实现:

1)停止和销毁 context 容器及其所有子容器,子容器其实就是 wrapper,也就是说 wrapper 里面 servlet 实例也被销毁了。

2)停止和销毁 context 容器关联的 listener 和 filter。

3)停止和销毁 context 下的 pipeline 和各种 valve。

4)停止和销毁 context 的类加载器,以及类加载器加载的类文件资源。

5)启动 context 容器,在这个过程中会重新创建前面四步被销毁的资源。

  • context 容器对应一个类加载器,类加载器在销毁的过程中会把它加载的所有类也全部销毁。
  • context 容器在启动过程中,会创建一个新的类加载器来加载新的类文件。

4.tomcat热部署

热部署跟热加载的本质区别是,热部署会重新部署 web 应用,原来的 context 对象会整个被销毁掉,因此这个 context 所关联的一切资源都会被销毁,包括 session。

host 容器并没有在 backgroundprocess 方法中实现周期性检测的任务,而是通过监听器 hostconfig 来实现的(hostconfig#lifecycleevent)

hostconfig 会检查 webapps 目录下的所有 web 应用:如果原来 web 应用目录被删掉了,就把相应 context 容器整个销毁掉。是否有新的 web 应用目录放进来了,或者有新的 war 包放进来了,就部署相应的 web 应用。

因此 hostconfig 做的事情都是比较“宏观”的,它不会去检查具体类文件或者资源文件是否有变化,而是检查 web 应用目录级别的变化。

2、jetty

开源的webserver/servlet容器,是基于 nio模型。

通过handler实现扩展简单。jetty和tomcat性能方面差异不大jetty可以同时处理大量连接而且可以长时间保持连接适合于web聊天应用等

1.替换默认的tomcat容器

<dependencies>
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
        <exclusions>
            <!-- 去除tomcat容器 -->
            <exclusion>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-starter-tomcat</artifactid>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- 增加jetty容器 -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-jetty</artifactid>
    </dependency>
</dependencies>

2.重要参数

是否打开jetty日志(默认关闭):server.jetty.accesslog.enabled

  • 访问日志所在目录:server.jetty.accesslog.dir
  • 最大线程数:server.jetty.threads.max
  • 最小线程数:server.jetty.threads.min
  • 最大队列容量:server.jetty.threads.max-queue-capacity
  • 线程最大空闲时间:server.jetty.threads.idle-timeout

3、undertow

轻量级:undertow 是非常小的,只有不到1mb。在内嵌模式下,运行时只占heap空间的4mb左右。

支持 servlet 3.1

web socket:支持 web socket (包括jsr-356)

长连接:默认情况下,undertow 通过添加keep-alive 的response header来支持长连接。它通过重用连接信息(connection details)来改善长连接的性能。

1.替换默认的tomcat容器

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web</artifactid>
    <exclusions>
      <!-- 去除 tomcat 容器 -->
        <exclusion>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-tomcat</artifactid>
        </exclusion>
    </exclusions>
</dependency>
  <!-- 添加 undertow 容器 -->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-undertow</artifactid>
</dependency>

2.重要参数

# undertow 日志存放目录
server.undertow.accesslog.dir=
# 是否启动日志
server.undertow.accesslog.enabled=false
# 日志格式
server.undertow.accesslog.pattern=common
# 日志文件名前缀
server.undertow.accesslog.prefix=access_log
# 日志文件名后缀
server.undertow.accesslog.suffix=log
# http post请求最大的大小
server.undertow.max-http-post-size=0
# 设置io线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个cpu核心一个线程
# 不要设置过大,如果过大,启动项目会报错:打开文件数过多
server.undertow.io-threads=12
# 阻塞任务线程池, 当执行类似servlet请求阻塞io操作, undertow会从这个线程池中取得线程
# 它的值设置取决于系统线程执行任务的阻塞系数,默认值是io线程数*8
server.undertow.worker-threads=20
# 以下的配置会影响buffer,这些buffer会用于服务器连接的io操作,有点类似netty的池化内存管理
# 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可
server.undertow.buffer-size=1024
# 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region
server.undertow.buffers-per-region=1024
# 是否分配的直接内存
server.undertow.direct-buffers=true

4、netty

1、springboot整合netty(服务端)

1.配置
<!-- netty -->
<dependency>
    <groupid>io.netty</groupid>
    <artifactid>netty-all</artifactid>
    <version>4.1.36.final</version>
</dependency>
# netty 配置
netty:
  # boss线程数量
  boss: 4
  # worker线程数量
  worker: 2
  # 连接超时时间
  timeout: 6000
  # 服务器主端口
  port: 17000
  # 服务器备用端口
  portsalve: 18026
  # 服务器地址
  host: 127.0.0.1
2.编写netty处理器
/**
 * socket拦截器,用于处理客户端的行为
 **/
@slf4j
public class sockethandler extends channelinboundhandleradapter {
    public static final channelgroup clients = new defaultchannelgroup(globaleventexecutor.instance);

    /**
     * 读取到客户端发来的消息
     */
    @override
    public void channelread(channelhandlercontext ctx, object msg) throws exception {
        // 由于我们配置的是 字节数组 编解码器,所以这里取到的用户发来的数据是 byte数组
        byte[] data = (byte[]) msg;
        log.info("收到消息: " + new string(data));
        // 给其他人转发消息
        for (channel client : clients) {
            if (!client.equals(ctx.channel())) {
                client.writeandflush(data);
            }
        }
    }

    @override
    public void handleradded(channelhandlercontext ctx) throws exception {
        log.info("新的客户端链接:" + ctx.channel().id().asshorttext());
        clients.add(ctx.channel());
    }

    @override
    public void handlerremoved(channelhandlercontext ctx) throws exception {
        clients.remove(ctx.channel());
    }

    @override
    public void exceptioncaught(channelhandlercontext ctx, throwable cause) throws exception {
        cause.printstacktrace();
        ctx.channel().close();
        clients.remove(ctx.channel());
    }
}
3.编写netty初始化器
/**
 * socket 初始化器,每一个channel进来都会调用这里的 initchannel 方法
 **/
@component
public class socketinitializer extends channelinitializer<socketchannel> {
    @override
    protected void initchannel(socketchannel socketchannel) throws exception {
        channelpipeline pipeline = socketchannel.pipeline();
        // 添加对byte数组的编解码,netty提供了很多编解码器,你们可以根据需要选择
        pipeline.addlast(new bytearraydecoder());
        pipeline.addlast(new bytearrayencoder());
        // 添加上自己的处理器
        pipeline.addlast(new sockethandler());
    }
}
4.编写netty服务
@slf4j
@component
public class socketserver {
    @resource
    private socketinitializer socketinitializer;

    @getter
    private serverbootstrap serverbootstrap;

    /**
     * netty服务监听端口
     */
    @value("${netty.port:17000}")
    private int port;
    /**
     * 主线程组数量
     */
    @value("${netty.boss:4}")
    private int bossthread;

    /**
     * 启动netty服务器
     */
    public void start() {
        this.init();
        this.serverbootstrap.bind(this.port);
        log.info("netty started on port: {} (tcp) with boss thread {}", this.port, this.bossthread);
    }

    /**
     * 初始化netty配置
     */
    private void init() {
        // 创建两个线程组,bossgroup为接收请求的线程组,一般1-2个就行
        nioeventloopgroup bossgroup = new nioeventloopgroup(this.bossthread);
        // 实际工作的线程组
        nioeventloopgroup workergroup = new nioeventloopgroup();
        this.serverbootstrap = new serverbootstrap();
        this.serverbootstrap.group(bossgroup, workergroup) // 两个线程组加入进来
                .channel(nioserversocketchannel.class)  // 配置为nio类型
                .childhandler(this.socketinitializer); // 加入自己的初始化器
    }
}
5.启动netty
/**
 * 监听spring容器启动完成,完成后启动netty服务器
 **/
@component
public class nettystartlistener implements applicationrunner {
    @resource
    private socketserver socketserver;

    @override
    public void run(applicationarguments args) throws exception {
        this.socketserver.start();
    }
}

2、netty客户端

客户端用nio来编写,在实际工作中客户端可能是 websocket、socket,以 socket 为例。

1.编写客户端线程
public class clientthread implements runnable{

    private final selector selector;

    public clientthread(selector selector) {
        this.selector = selector;
    }

    @override
    public void run() {
        try {
            for (; ; ) {
                int channels = selector.select();
                if (channels == 0) {
                    continue;
                }
                set<selectionkey> selectionkeyset = selector.selectedkeys();
                iterator<selectionkey> keyiterator = selectionkeyset.iterator();
                while (keyiterator.hasnext()) {
                    selectionkey selectionkey = keyiterator.next();

                    // 移除集合当前得selectionkey,避免重复处理
                    keyiterator.remove();
                    if (selectionkey.isreadable()) {
                        this.handleread(selector, selectionkey);
                    }
                }
            }
        } catch (ioexception e) {
            e.printstacktrace();
        }
    }

    // 处理可读状态
    private void handleread(selector selector, selectionkey selectionkey) throws ioexception {
        socketchannel channel = (socketchannel) selectionkey.channel();
        bytebuffer bytebuffer = bytebuffer.allocate(1024);
        stringbuilder message = new stringbuilder();
        if (channel.read(bytebuffer) > 0) {
            bytebuffer.flip();
            message.append(standardcharsets.utf_8.decode(bytebuffer));
        }
        // 再次注册到选择器上,继续监听可读状态
        channel.register(selector, selectionkey.op_read);
        system.out.println(message);
    }
}
2.客户端逻辑
public class chatclient {

    public void start(string name) throws ioexception {
        socketchannel socketchannel = socketchannel.open(new inetsocketaddress("127.0.0.1", 8088));
        socketchannel.configureblocking(false);
        selector selector = selector.open();
        socketchannel.register(selector, selectionkey.op_read);

        // 监听服务端发来得消息
        new thread(new clientthread(selector)).start();
        // 监听用户输入
        scanner scanner = new scanner(system.in);
        while (scanner.hasnextline()) {
            string message = scanner.nextline();
            if (stringutils.hastext(message)) {
                socketchannel.write(standardcharsets.utf_8.encode(name + ": " + message));
            }
        }
    }
}
3.客户端
public class client1 {
    public static void main(string[] args) throws ioexception {
        new chatclient().start("李四");
    }
}
public class client2 {
    public static void main(string[] args) throws ioexception {
        new chatclient().start("张三");
    }
}

三、重要组件

  • spring core:spring的核心组件,提供ioc、aop等基础功能,是spring全家桶的基础。
  • spring boot:一个基于spring framework的快速开发框架,可以快速创建独立的、生产级别的spring应用程序。
  • spring cloud:一个用于构建分布式应用程序的框架,提供了诸如服务发现、配置管理、负载均衡等功能。
  • spring data:用于简化数据访问层开发的框架,提供了一系列数据访问模板和持久化技术的集成。
  • spring security:一个用于处理应用程序安全的框架,提供了认证、授权、安全防护等功能。
  • spring integration:spring integration是一个用于构建企业级集成解决方案的框架,支持将不同的应用程序和服务集成到一起。它提供了许多组件和模式,如消息通道、消息端点、消息路由器、过滤器等。
  • spring batch:spring batch是一个用于处理大量数据和批处理作业的框架。它提供了各种工具和组件,如任务启动器、作业仓库、作业执行器、步骤处理器、读写器等。
  • spring web services:spring web services是一个用于构建基于soap协议的web服务的框架。它提供了各种组件和工具,如消息处理器、绑定器、端点等,使得构建web服务更加容易。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com