Maven简介

Maven简介

什么是Maven

Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型 (POM)

如图蓝色部分为 Maven,其不包括外部其他部分,上部分为核心,下部分为各种插件。Maven 的作用如下

  • 项目构建: 提供标准的、跨平台的自动化项目构建方式
  • 依赖管理: 方便快捷的管理项目依赖的资源包,避免资源之间的版本冲突问题
  • 统一开发结构: 规定了 src、resource、target 等统一项目结构

Maven 是由 Java 语言编写的,同样采用了面向对象的思想

Maven安装

  1. 点击进入 Maven 官网进行下载 maven.apache.org/
  2. 解压文件到没有空格、没有中文的目录下
  3. 【可选】打开 maven目录/conf/settings.xml 配置文件,配置阿里镜像地址(配置到 <mirrors> 标签里)
xml 复制代码
<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>https://maven.aliyun.com/repository/central/</url>
    <mirrorOf>central</mirrorOf>
</mirror>
  1. 【可选】配置环境变量:新建 MAVEN_HOME:Maven根目录,修改Path添加 %MAVEN_HOME%\bin (注意:Maven 依赖环境变量中有 JAVA_HOME),CMD输入 mvn -v 验证
  2. 【可选】因为Java默认的最大可用内存往往不够满足Maven运行需要,比如较大的项目时,使用Maven生成项目站点需要占用大量内存,可选配置 MAVEN_OPTS:-Xms128m -Xmx512m

注意 Maven 是由 Java 研发的,所以 Maven 依赖 Java

Maven概念

仓库概念:仓库用于存储资源(各种 Jar 包),其分为本地仓库 、远程仓库 、中央仓库

  • 本地仓库: 自己电脑上存储资源的仓库
  • 远程仓库: 也叫作 Maven 私服,部门/公司范围内储存资源的仓库
  • 中央仓库: Maven 团队维护的,维护所有资源的仓库

坐标概念:坐标用于描述仓库中资源的位置,其构成部分及说明如下:

  • gourpId:组织名,定义该 Maven 项目隶属组织,常是域名反写,如 org.example.demo
  • artifactId:项目名,定义该 Maven 项目名称
  • version:版本号,定义该 Maven 项目的版本号
  • packaging:定义项目的打包方式,如成果物类型 war 或 jar,如组织项目的 pom 类型

Jar 包的获取会逐级搜索,如本地仓存在则直接使用本地仓,如不存在则到远程仓获取。以此类推

Maven使用

生命周期命令

命令 说明
mvn archetype:generate 创建 Maven 项目,可通过参数指定坐标等 可以使用骨架:常用7号 quickstart 普通项目,10号 webappWEB 项目
mvn clean 把已经编译好的项目的所有信息清除(target 文件夹)
mvn compile 自动导入 POM 中的依赖,并把核心代码部分编译后,放置在 target 目录下
mvn test 通过此命令可以执行 test 文件夹下的测试用的内容,实现项目测试(同时执行了 compile)
mvn package 将 Maven 项目进行打包,放置在 target 目录下(同时执行了 test)
mvn install 将刚刚项目打完的包安装到本地仓库,由 maven 进行管理(同时执行了 package)
mvn deploy 项目发布,将 maven 本地库中管理的资源发布到远程库中

POM文件结构

xml 复制代码
<!--当前项目的maven资源坐标-->
<groupId>org.example</groupId>
<artifactId>MVNDemo01</artifactId>
<version>1.0-SNAPSHOT</version>

<!--此项目在mvn package的过程中,要打成什么样的包,通常是jar或war,也可能是pom-->
<packaging>jar</packaging>

<!-- 项目相关信息 -->
<name>MVNDemo01</name>
<description>xxx</description>
<url>http://maven.apache.org</url>

<!-- 参数配置 -->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!-- 依赖管理 -->
<dependencies>
    <dependency>
    </dependency>
</dependencies>

<!-- 依赖版本管理 -->
<dependencyManagement>
</dependencyManagement>

<!-- 项目构建 -->
<build>
    <plugins>
        <plugin>
        </plugin>
    </plugins>
</build>

依赖传递

依赖是可以传递的,很有可能会发生依赖传递冲突问题,其优先级如下:

  1. 路径优先: 当依赖中出现相同的资源时(可能版本号不同),层级越浅,优先级越高
  2. 声明优先: 当资源在相同层级被依赖时,配置顺序考前的覆盖配置顺序靠后的
  3. 特殊优先: 当在同 POM 文件中声明时,后配置的覆盖先配置的

处理依赖传递有如下两种标签:

  • 可选依赖: 控制引用该资源的项目无法看到该依赖
  • 排除依赖: 主动排除掉该资源中的指定依赖
xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>springboot</artifactId>
    <version>1.1</version>
    <!-- 可选依赖(默认false,可传递) -->
    <optional>true</optional>
    <!-- 排除依赖 -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>bbb</artifactId>
        </exclusion>
    </exclusions>
</dependency>

依赖范围

依赖范围: 可以通过 <scope> 标签指定其依赖范围,其作用如下:

scope 编译 测试 打包 范例
compile(默认) Y Y Y log4j
test Y junit(仅测试使用)
provided Y Y 不传递 servlet-api(Tomcat中包含)
runtime Y jdbc(可防止编写时意外导入)
system Y Y 插件配置 includeSystemScope 依赖来自本地系统,需要配合标签 systemPath 使用
import 引入依赖项目,配合 <type>pom</type> 使用

依赖范围具有传递性,开发时根据实际情况使用

插件使用

插件的使用可以通过官网查询,不同插件有不同使用方式,根据文档说明进行操作。如下简单示例源码插件配置

xml 复制代码
<build>
    <plugins>
        <!-- 使用具体插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
            <!-- 配置执行条件/位置:具体使用参考插件文档 -->
            <executions>
                <execution>
                    <!-- 操作目标,如下为主代码及test代码 -->
                    <goals>
                        <goal>jar</goal>
                        <goal>test-jar</goal>
                    </goals>
                    <!-- 插件执行阶段(生命周期哪个阶段) -->
                    <phase>generate-resources</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

多模块管理

Model聚合

聚合 用于快速构建 Maven 工程,一次性构建多个项目/模块。如多个项目/模块依赖,执行命令时需要每一个工程都进行编译,打包,安装,测试,部署等生命周期的命令,一个一个去执行这些命令效率非常低

Maven 提供了聚合的配置,实现统一执行命令,实现方法:创建一个无代码聚合工程,并在 POM 中配置所有聚合的项目/模块

xml 复制代码
<!-- 打包类型为聚合 -->
<packaging>pom</packaging>
<!-- 配置模块名称 -->
<modules>
    <!-- 标签内部值为子模组pom.xml所在路径 -->
    <!-- 表示与自己同级的child1项目目录 -->
    <module>../child1</module>
    <!-- 表示为自己目录下child2项目目录 -->
    <module>child2</module>
  </modules>

只是聚合项目关心有什么模块,模块不需要知道被谁聚合了

Maven继承

Maven 项目提供继承 的特性,可以利用继承实现所有项目资源版本统一的问题。其继承的父类资源包括:

继承项 说明
groupId version 项目相关的内容。可以重写,默认父类的值
properties 父级工程在 properties 标签中定义的变量,子工程使用 ${} 使用
dependencies 相当于强制继承,子工程中一定被导入父工程该标签内的 Jar 包
dependencyManagement 常用的一种统一资源的继承方式,只会继承版本而不会强制让子工程依赖资源 子工程通过在 dependency 内添加 groupId 和 artifactId 即可,当然也可以重写 version 版本号
build pluginManagement 如上的一种统一资源的继承方式,其使用如上,不仅继承版本号,还会继承声明的使用方式

继承 的实现需要子项目声明父项目,注意 Maven 是单继承,其声明方式如下:

xml 复制代码
<!-- 定义工程的父工程 -->
<parent>
    <groupId>org.example.parent</groupId>
    <artifactId>demo-parent</artifactId>
    <version>1.0.0.RELEASE</version>
    <!-- 填写父工程的POM位置,省略不写视为在父工程内/父工程为远程项目,仓库获取 -->
    <relativePath>../parent/pom.xml</relativePath>
</parent>

只是子项目声明了父项目是谁,父项目不需要知道被谁继承了

属性管理

Maven 提供属性管理,其管理方式属性类型有:自定义属性 、内置属性 、Setting属性 、Java系统属性 、环境变量属性

xml 复制代码
<!-- 定义自定义属性 -->
<properties>
    <mybatis-plus.version>3.1.2</mybatis-plus.version>
    <druid.version>1.1.17</druid.version>
</properties>

<!-- 使用自定义属性 -->
<version>${druid.version}</version>

<!-- 内置属性:含 ${basedir} ${version} 等 -->

<!-- Setting属性:配置文件 setting.xml 中的标签属性,属于动态属性,如 ${settings.localRepository} 等 -->

<!-- Java系统属性、环境变量属性:通过命令 mvn help:system 可以获取到属性 -->

Maven 提供资源加载属性值功能,其为项目内的其他资源文件使用定义的自定义属性,调用方式相同 ${} 使用如下

xml 复制代码
<!-- 定义哪个文件夹下文件开启POM属性过滤功能,检测到 ${} 就替换属性 -->
<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtreing>true<filtering>
        </resource>
    </resources>
</build>

版本管理含 RELEASE 和 SNAPSHOT,正式版、快照版
Maven 可以进行多环境配置参数,通过打包命令添加参数完成,可了解一下

Maven私服

【Nexus】为常用私服,安装及使用绕道参考

常用插件使用

JDK版本

更改编译 Java 源码的 jdk 版本

xml 复制代码
<!-- 通过更改项目的 pom.xml,添加 java 编译插件 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

<!-- 或者在 properties 设置 jdk 版本 -->
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
 </properties>

更改 Maven 默认 的 JDK 版本,更改 Maven 目录下的 conf/settings.xml 文件,以后建立的项目源码编译都是指定的 jdk 版本

xml 复制代码
<profile>
    <id>jdk-1.8</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>
    </activation>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>

各种常用插件

xml 复制代码
<!-- Spring项目打包插件:可能和 appassembler-maven-plugin 不兼容 -->
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<!-- 测试插件:不写进行默认测试,这里配置了该插件跳过测试 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

<!-- 应用不部署到远程仓库中 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

Appassembler打包

Appassembler 打包有三种核心打包方式,其中常用打包为可执行程序 和守护服务 方式。如下介绍最为常用的守护方式,该方式可生成资源后直接在服务器中运行为服务

Appassembler 打包方式的优点:

  1. 通过 wrapper 方式进行管理,直接运行 bin/ 下的可执行文件 start | stop | console | restart
  2. 分包管理 lib 依赖,其打包方式不会将所有依赖打包到一个可执行文件中,分包管理,方便更改部分 jar 包代码,进行部分更新
  3. 管理资源文件,可以通过设置,让程序首先使用 conf/ 文件夹下的资源/配置文件,当找不到时才找 jar 包内资源
  4. 当更新程序时,操作步骤更为简单:
  5. 把需要更新的 jar 包覆盖到 lib/ 下
  6. 保证是否需要更新配置文件 conf/
  7. 运行可执行文件 xxx restart 重启服务
xml 复制代码
<!-- 使用说明: -->
<!-- 1. 修改对应的项目名称 -->
<!-- 2. 修改属性值,输出文件夹目录 -->
<!-- 3. 修改启动类,如下 mainClass 标签 -->

<!-- 配置项目名称及属性,后期配置使用 -->
<name>demo</name>
<properties>
    <appassembler.out.name>appassembler-out</appassembler.out.name>
</properties>

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>appassembler-maven-plugin</artifactId>
    <version>2.1.0</version>
    <!-- 配置插件启动时机 -->
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>generate-daemons</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- 打包后生成的目录位置及各目录 -->
        <target>${project.build.directory}/${appassembler.out.name}</target>
        <binFolder>bin</binFolder>
        <logsDirectory>logs</logsDirectory>
        <repositoryName>lib</repositoryName>
        <!-- 为系统配置文件指定一个目录 -->
        <configurationDirectory>conf</configurationDirectory>
        <!-- 源代码中对应的系统配置文件的位置 -->
        <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
        <!-- 是否将配置文件包含到classpath -->
        <includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
        <!-- 是否拷贝源代码中配置文件中的目录 -->
        <copyConfigurationDirectory>true</copyConfigurationDirectory>
        <!-- 依赖的lib包的目录格式,flat表示不分目录平铺到lib目录下 -->
        <repositoryLayout>flat</repositoryLayout>
        <daemons>
            <daemon>
                <!-- 基本信息配置:名称及启动类 -->
                <id>${project.name}</id>
                <mainClass>org.example.Starter</mainClass>
                <!-- JVM配置设置 -->
                <jvmSettings>
                    <maxStackSize>128</maxStackSize>
                    <extraArguments>
                        <extraArgument>-server</extraArgument>
                        <extraArgument>-XX:+AggressiveOpts</extraArgument>
                        <extraArgument>-Xmx1G</extraArgument>
                        <extraArgument>-XX:+HeapDumpOnOutOfMemoryError</extraArgument>
                    </extraArguments>
                </jvmSettings>
                <!-- 打包平台配置 -->
                <platforms>
                    <platform>jsw</platform>
                </platforms>
                <generatorConfigurations>
                    <generatorConfiguration>
                        <generator>jsw</generator>
                        <includes>
                            <!-- include>linux-x86-32</include -->
                            <!-- include>linux-ppc-64</include -->
                            <include>linux-x86-64</include>
                            <include>windows-x86-64</include>
                        </includes>
                        <configuration>
                            <!-- 手动添加一个系统启动时依赖的第一个classpath,这里通常写为配置文件的目录名,如果不配置,配置文件无法找到 -->
                            <property>
                                <name>configuration.directory.in.classpath.first</name>
                                <value>conf</value>
                            </property>
                            <!-- 依赖jar包位置 -->
                            <property>
                                <name>set.default.REPO_DIR</name>
                                <value>lib</value>
                            </property>
                            <!-- 日志文件位置 -->
                            <property>
                                <name>wrapper.logfile</name>
                                <value>logs/wrapper-${project.name}.log</value>
                            </property>
                            <!-- 日志文件格式:MB兆的方式格式 -->
                            <property>
                                <name>wrapper.logfile.format</name>
                                <value>M</value>
                            </property>
                            <!-- 日志文件最大值:10MB -->
                            <property>
                                <name>wrapper.logfile.maxsize</name>
                                <value>10m</value>
                            </property>
                            <!-- 日志文件最大分割值:5 -->
                            <property>
                                <name>wrapper.logfile.maxfiles</name>
                                <value>5</value>
                            </property>
                            <!-- 配置Windows服务:效果未检测 -->
                            <property>
                                <name>wrapper.ntservice.interactive</name>
                                <value>true</value>
                            </property>
                        </configuration>
                    </generatorConfiguration>
                </generatorConfigurations>
            </daemon>
        </daemons>
    </configuration>
</plugin>

该插件可能与 Spring Boot 打包插件冲突,如出现找不到主类清单错误,可选择注释掉 Spring Boot 打包插件(spring-boot-maven-plugin)

Assembly打包

Assembly 打包是 Maven 提供的一种打包方式,可以输出自定义的包类型。如上输出守护服务 的资源后,可以再通过该插件进行打包输出

xml 复制代码
<!-- 集合打包插件 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <!-- 只执行一次 -->
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- 描述文件所在位置 -->
        <descriptors>
            <descriptor>src/main/assembly/assembly-linux.xml</descriptor>
            <descriptor>src/main/assembly/assembly-win.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>

描述文件用于描述输出文件,如下输出两个压缩文件(文件内容来自上个插件的输出结果)

xml 复制代码
<!-- src/main/assembly/assembly-linux.xml -->
<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>linux</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>tar.gz</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory>
            <outputDirectory>${project.name}/bin</outputDirectory>
            <fileMode>0755</fileMode>
            <includes>
                <include>${project.name}</include>
                <include>wrapper-linux*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory>
            <outputDirectory>${project.name}/lib</outputDirectory>
            <includes>
                <include>*.jar</include>
                <include>libwrapper-linux*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory>
            <outputDirectory>${project.name}/conf</outputDirectory>
            <includes>
                <include>*.yml</include>
                <include>banner.txt</include>
                <include>wrapper.conf</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory>
            <outputDirectory>${project.name}/logs</outputDirectory>
            <excludes>
                <exclude>**/*</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>
xml 复制代码
<!-- src/main/assembly/assembly-win.xml -->
<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>win</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>zip</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory>
            <outputDirectory>${project.name}/bin</outputDirectory>
            <fileMode>0755</fileMode>
            <includes>
                <include>${project.name}</include>
                <include>wrapper-windows*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory>
            <outputDirectory>${project.name}/lib</outputDirectory>
            <includes>
                <include>*.jar</include>
                <include>libwrapper-windows*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory>
            <outputDirectory>${project.name}/conf</outputDirectory>
            <includes>
                <include>*.yml</include>
                <include>banner.txt</include>
                <include>wrapper.conf</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory>
            <outputDirectory>${project.name}/logs</outputDirectory>
            <excludes>
                <exclude>**/*</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>

资源打包插件

Maven 项目默认资源在 src/main/resources 目录下,如果资源不在此目录下,需要添加 maven-resources-plugin 插件,并在 resource 中配置资源路径

xml 复制代码
<!-- 资源打包插件 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
</plugin>

<!-- 配合 resources 插件添加资源目录 -->
<resources>
    <resource>
        <directory>src/main/resources</directory>
        <!-- 打开变量替换声明 -->
        <!-- filtering>true</filtering -->
    </resource>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>

Tomcat插件

下面介绍的是 tomcat7 插件在 pom.xml 文件中的配置,端口默认是 8080,path 默认是项目名称(可以在 configuration 标签内进行修改)。执行命令 mvn tomact7:run 运行

xml 复制代码
<!-- 构建 -->
<build>
    <plugins>
        <!-- 添加tomcat服务器插件 -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <!-- 配置tomcat端口 -->
                <port>8080</port>
                <!-- Web应用的访问路径
                <path>HelloWorld</path>
                -->
                <!-- 配置tomcat编码,解决GET乱码 -->
                <uriEncoding>UTF-8</uriEncoding>
            </configuration> 
        </plugin>
    </build>
</plugins>

使用技巧

清理小工具

Maven 本地仓库同步的时候会产生很多不存在的 Jar 包下载准备文件,可以通过该命令行脚本进行清理,保存到 .bat 文件中,在 windows 双击使用

bash 复制代码
set REPOSITORY_PATH=E:\MavenRepo
rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (
    del /s /q %%i
)
rem 搜索完毕
pause
相关推荐
步行cgn20 小时前
Spring 全注解开发详解
java·后端·spring
IT_陈寒1 天前
SpringBoot启动慢得像蜗牛?原来是这个配置在捣鬼
前端·人工智能·后端
不才不才不不才1 天前
Spring 源码系列(29): 20 道高频面试题源码级解析合集
java·后端·spring
索隆zoro1 天前
Army 的可插拔架构:army-jdbc 与方言模块
java·后端
小蒜学长1 天前
校园社团招新网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·校园社团招新网站
蜗牛互联网1 天前
从Barclays扩大Claude部署看受监管软件工程的责任重分配
java·大数据·人工智能·后端·软件工程
周杰伦fans1 天前
C#对话摘要降低Token消耗
人工智能·后端·c#
做系统的大强1 天前
脚本说 PASS、OS 读全零 —— 到底是谁在撒谎?
后端·操作系统
code2cat1 天前
【随笔】MCP资源更新订阅:通知到达以后,Agent怎样刷新旧资料
java·后端·开发工具·ai agent·mcp
Harvil_1 天前
任务跑一半,API 突然报“对话超长“断流:我给 Agent 修的紧急逃生通道
后端