主项目 pybbs,启动类包名 co.yiiu.pybbs
配置了扫描包 @SpringBootApplication(scanBasePackages = "co.yiiu.pybbs")
另外创建了一个 maven 项目,写了一个 bean,名包是 co.yiiu.pybbs.plugin
类上也加了 @Component
注解
首先我把新建的 maven 项目通过 mvn install
安装到本地,然后在 pybbs 里通过 pom 引入,启动项目测试没有问题,可以扫描到新建包中的 bean 以及方法的调用
然后我又通过 mvn assembly:assembly
把 pybbs 打包了,在 assembly 里配置了程序 jar 包和引入信赖 jar 包分享的方式来打包的,生成的目录中会有一个 lib 文件夹,然后我把新建的 maven 项目也打成 jar 包,然后拷贝到 pybbs/lib 目录中,启动项目就有问题了,spring 不会去扫描 jar 包中的 bean,方法也没有生效
求问:
spring 怎么加载外部 jar 包中的 bean 呢?
下面有我两个项目的配置,大佬们帮忙看下是我哪配置错了吗?万分感谢!!!
pybbs 中的 pom.xml build 配置
<build>
<finalName>pybbs</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<!--springboot 插件
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>-->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- 如果是 true 在打出来的包 /路径上面会增加这个 Assembly 的 id 显示-->
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<!-- assembly 描述文件位置 -->
<descriptor>src/main/resources/assembly.xml</descriptor>
</descriptors>
<!-- 打包完成后文件输出位置 这里为 target 目录-->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
<plugin>
<!-- 主要用来打包主 jar-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<!--启动文件入口类,就是 springboot 启动 main 方法所在类 -->
<mainClass>co.yiiu.pybbs.PybbsApplication</mainClass>
<!-- 主 jar 依赖的 jar 包路径-->
<classpathPrefix>lib/</classpathPrefix>
<addClasspath>true</addClasspath>
</manifest>
<!--<manifestEntries>
<!– 在 Class-Path 下添加配置文件的路径 –>
<Class-Path>resources</Class-Path>
</manifestEntries>-->
</archive>
<!-- 不把配置文件和 html 文件打进主 jar 内-->
<excludes>
<exclude>*.java</exclude>
<exclude>static/</exclude>
<exclude>db/</exclude>
<exclude>templates/</exclude>
<exclude>*.yml</exclude>
<exclude>*.txt</exclude>
<exclude>logback.xml</exclude>
</excludes>
</configuration>
</plugin>
<!-- 打包发布时,跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
assembly.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>package</id>
<formats>
<!-- 打包成目录,这里其实有很多选择,如 dir,jar,war,zip 等,我们这里选择先打成目录,到真正要用的时候可以打包成 zip-->
<format>tar.gz</format>
<!--<format>dir</format>-->
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- 把项目相关的说明文件,打包进 zip 文件的根目录 -->
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory></outputDirectory>
<excludes>
<exclude>logback.xml</exclude>
<exclude>static/**</exclude>
<exclude>*.json</exclude>
<exclude>pom.xml</exclude>
<exclude>target/**</exclude>
<exclude>mysql/**</exclude>
<exclude>docs/**</exclude>
<exclude>logs/**</exclude>
<exclude>src/**</exclude>
<exclude>sql/**</exclude>
<exclude>.idea/**</exclude>
<exclude>.gitignore</exclude>
<exclude>.classpath</exclude>
<exclude>.factorypath</exclude>
<exclude>.project</exclude>
<exclude>application.pid</exclude>
<exclude>pybbs.iml</exclude>
<exclude>pybbs.pid</exclude>
<exclude>.settings/**</exclude>
<exclude>Dockerfile</exclude>
<exclude>docker-compose.yml</exclude>
<exclude>application-docker.yml</exclude>
<exclude>application-dev.yml</exclude>
</excludes>
</fileSet>
<!-- 把项目的配置文件,打包进 zip 文件的根目录 -->
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory></outputDirectory>
<excludes>
<exclude>assembly.xml</exclude>
<exclude>static/upload/**</exclude>
<exclude>i18n/**</exclude>
</excludes>
<!-- <excludes>
<exclude>**</exclude>
</excludes>-->
</fileSet>
<!-- 把项目的脚本文件,打包进 zip 文件的 bin 目录-->
<fileSet>
<directory>${project.basedir}/src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
<excludes>
<exclude>target/**</exclude>
<exclude>*.json</exclude>
<exclude>static/**</exclude>
<exclude>templates/**</exclude>
</excludes>
</fileSet>
</fileSets>
<dependencySets>
<!-- 打包依赖文件,就是 maven 里面那一堆 jar 包-->
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<scope>runtime</scope>
<!-- 除了主 jar 文件都打到 lib 目录下-->
<excludes>
<exclude>${project.groupId}:${project.artifactId}</exclude>
</excludes>
</dependencySet>
<!-- 主 jar 打到根目录,因为 pom 文件中设置主 jar 的依赖包目录为 lib/-->
<dependencySet>
<outputDirectory>/</outputDirectory>
<outputFileNameMapping>${artifact.artifactId}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
<includes>
<include>${project.groupId}:${project.artifactId}</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
新建 maven 项目中 pom.xml build 节点配置
<build>
<finalName>pybbs-redis-cache-plugin</finalName>
<plugins>
<!-- 编译指定 jdk 版本号 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<!-- 部署带上源文件, 可以在引入依赖时看到源码, 以及源码上的注释信息 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<includePom>true</includePom>
<excludeResources>true</excludeResources>
<attach>true</attach>
</configuration>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
1
happypy1 2019-06-07 10:59:01 +08:00
|
2
visaxin906 2019-06-07 11:01:08 +08:00
spring context -> read xml -> scan bean
|
4
tomoya92 OP @visaxin906 #2 你的意思是在 jar 包中写一个 xml 来声明 jar 包中的 bean,然后在 pybbs 里通过
|
5
tomoya92 OP @tomoya92 #4 你的意思是在 jar 包中写一个 xml 来声明 jar 包中的 bean,然后在 pybbs 里通过 applicationContext 来读取 jar 包中的 xml 配置文件从而达到加载 jar 包中的 bean 的目的吗?
|
6
br00k 2019-06-07 14:07:50 +08:00
你应该使用 starter 组件开发。在组件 spring.factories 的配置里指定配置文件,在配置文件里注解设置包扫描路径。
|
7
c4f36e5766583218 2019-06-07 14:18:51 +08:00
1. 使用包扫描扫到那个 bean (如果这个 bean 有扫描注解)
2. xml 配置 3. java 配置 |
8
limuyan44 2019-06-07 16:28:40 +08:00 via Android
按 spring 方式正常引就好了,不是入门的基础吗。
|
9
MoHen9 2019-06-07 21:50:21 +08:00 via Android
如果普通方式运行是正常的,那就是打包的原因了,真的将依赖和配置打包进去的话,不应该出现扫描不到的问题,建议用解压软件看看打的 jar 结构,从来没用过 mvn assembly 这种命令打包,一般不是用 mvn build 打包吗?
|
10
Leiothrix 2019-06-07 22:36:32 +08:00
老哥,
|
11
Leiothrix 2019-06-07 22:42:13 +08:00
老哥,你新建的那个 maven 项目也有 Spring Boot 的依赖吗?如果有依赖且存在启动类的话是不可以直接打成 jar 包作为依赖的哦,这是一个陷阱。可执行 Spring Boot 项目打出来的默认 jar 包不可以作为依赖。你可以去查阅一下相关材料,然后最好建一个普通的 maven 项目去放置通用的 common 类。
|
13
tomoya92 OP |
14
tomoya92 OP @MoHen9 #9 貌似找到原因了,在主项目里打包后,生成的 jar 包里有个 MANIFEST.MF 文件,里面定义了 Class-Path: xxx.jar 所有依赖的 jar 包都在这定义好了,所以项目在启动的时候才会加载这些 jar 包
我新建的那个 maven 项目打成的 jar 包没有引入到项目的 pom 文件里,所以在打主项目的 jar 包时,这个 Class-Path 里就没有我开发的那个 jar 包,这也导致了项目启动的时候不加载它 原因找到了,然后我就在尝试配置 maven-jar-plugin 插件,增加上了 lib/* 打包识别不了,换成 lib/*.jar 也识别不了,这个插件好像不支持通配符 然后就只能在启动项目之后,手动去使用 spring 的一些工具类将插件里开发的类加载到 ioc 容器里了,现在还没有折腾出来。。 |