【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】

文章目录

    • 项目新建
      • 项目结构
      • 选择SpringCloud Alibaba 版本
      • 统一管理项目依赖
      • 关于启动失败的报错分析:
        • 1、BaseMapper 启动错误
        • 2、SLF4J 报错
        • 3、使用Maven Helper检查依赖冲突
        • 4、启动项目不打印日志
        • 4、Dependency not found
      • 无报错启动的SpringBoot依赖
      • OpenJDK11手动生成jre文件夹
      • IDEA中需要指定JDK的地方

有理解不深刻、不恰当的地方欢迎指出。

项目新建

新建一个Maven项目,删掉src文件夹,就作为父项目。
子项目建立在这个之下。

项目结构

【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第1张图片
现在只做登录验证,其它子项目只是建起来不写什么。

选择SpringCloud Alibaba 版本

【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第2张图片

当前最新版本为2021.0.4.0
在 github 的 wiki里可以看到对版本依赖的描述:

https://github.com/alibaba/spring-cloud-alibaba/wiki
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第3张图片
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第4张图片
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第5张图片

最终确定版本:

  • SpringCloud: 2021.0.4.0
  • SpringBoot: 2.6.11
  • Sentinel: 1.8.5
  • Nacos: 2.0.4
  • RoketMQ: 4.9.4

(说明中没有明确指出2021.0.4.0版本到底用什么版本的Dubbo,自己不会,暂时不管这个。)

统一管理项目依赖

我的想法是这样的:
1、父项目的pom文件中,使用properties规定版本号、dependencyManagement把可能用到的依赖写进去。
2、使用SpringCloud,每个子项目(服务)导入依赖时,只指定依赖名,而不需要指定版本号。

在子项目中:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第6张图片

创建一个启动类加上启动类注解和扫描组件的注解:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第7张图片

注意: 此处我使用的是JDK11,主机装的是JDK1.8,需要改成使用JDK11开发。)

关于启动失败的报错分析:

1、BaseMapper 启动错误

报错信息:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.cat.auth.mapper.UserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656) ~[spring-beans-5.3.22.jar:5.3.22]
	... 71 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:8710', transport: 'socket'

Process finished with exit code 1

错误信息主要在于:

Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException:

No qualifying bean of type ‘com.cat.auth.mapper.UserMapper’ available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

原因没有找到 BaseMapper 对应的实现,没法注入,实际上我在子项目中导入的是:

            
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plusartifactId>
                <version>${mybatis-plus.version}version>
            dependency>

通过百度和试验验证:

仅仅导入 mybatis-plus 的依赖,虽然支持BaseMapper接口继承,但实际上没有对应的实现类。

不使用mybatis-plus依赖,改成直接使用mybatis-plus-boot-starter
mybatis-plus-boot-starter 提供了基本的Mapper实现。

            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-boot-starterartifactId>
                <version>${mybatis-plus-boot-starter.version}version>
            dependency>

刷新依赖再启动就不报错了。

2、SLF4J 报错

报错信息:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to 1.8.
SLF4J: Ignoring binding found at [jar:file:/D:/Program%20Files/apache-maven-3.8.6/repository/ch/qos/logback/logback-classic/1.2.11/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#ignoredBindings for an explanation.

之前忘了导入sl4j及相关的依赖,sl4j使用需要保持以下三个依赖:

(1)slf4j-api
(2)slf4j-reload4j (原 slf4j-log4j12)
(3)log4j-core (原 log4j)

或者两个依赖的版本:

(1)slf4j-api
(2)slf4j-simple

关于sl4j的使用,可以参考官网给出的使用手册:

https://www.slf4j.org/manual.html
(有时间单独写一篇短文介绍一下)

我选择的版本是全部最新版:

            <dependency>
                <groupId>org.slf4jgroupId>
                <artifactId>slf4j-apiartifactId>
                <version>2.0.5version>
            dependency>
            <dependency>
                <groupId>org.slf4jgroupId>
                <artifactId>slf4j-reload4jartifactId>
                <version>2.0.5version>
            dependency>
            <dependency>
                <groupId>org.apache.logging.log4jgroupId>
                <artifactId>log4j-coreartifactId>
                <version>2.19.0version>
            dependency>

引入后启动仍旧有爆红信息:

log4j:WARN No appenders could be found for logger (org.springframework.boot.env.OriginTrackedYamlLoader).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

根据提示,大概能知道意思:
log4j:WARN Please initialize the log4j system properly.
也就是需要我们初始化log4j的一些设置。
在这个子项目的resource目录下,新建一个log4j.prope文件:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第8张图片
复杂的配置这里不多写,先把项目跑起来不报错再说。
log4j.properties的内容(根据功能需要,还会继续修改):

log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

3、使用Maven Helper检查依赖冲突

IDEA里直接搜索Maven Helper安装,重启IDEA后,打开pom文件,发现pom文件下发多出一个选择:
在这里插入图片描述
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第9张图片
从上图中可以看出,有时候各种依赖本身都会依赖一些别的项目,很容易发生版本间的冲突。

这个工具可以帮助扫描当前的pom中依赖版本的冲突问题。

右键冲突的版本,Exclude就可以自动帮忙在pom文件里生成忽略信息:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第10张图片
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第11张图片
然后只要刷新一下maven,就可以了。

Maven Helper工具生成的标签,是在我们检查的这个子项目的pom文件中,我们应该把这一段复制到父项目的pom中。子项目不用引入。)

上图中:

因为依赖的mybatis-plus-boot-startermybatis-plus版本太高,甚至连spring-core等多个包都和我引入的spring-boot-starter-web有依赖冲突。

本来以为降低一下版本就可以了,结果发现mybatis-plus-boot-starter许多版本,没有一个能契合spring.boot-web.version 2.6.11版本
只能将标红的都exclude

不过还是要说:

  • 有时候,有合适的对应版本的依赖能够契合,当然优先选择降低或者调高到对应版本。
  • 如果不好找对应版本或者确实需要兼容,才选择exclusions
  • exclusions标签只在父项目dependencyManagement管理就可以,子项目依旧不用引入。

4、启动项目不打印日志

在解决依赖冲突过程中发现一个问题:

1、本身mybatis-plus-boot-starter与我引入的spring-boot-starter-web存在sl4j-api版本的依赖冲突,这个依赖冲突十分严重,直接导致控制台无法输出springboot的日志。
实际上程序已启动成功,接口也能正常访问,但控制台就是没有springboot的日志。
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第12张图片

解决上述依赖的办法是:
mybatis-plus-boot-starter内加入

                    <exclusion>
                        <artifactId>slf4j-apiartifactId>
                        <groupId>org.slf4jgroupId>
                    exclusion>

前提是,不能在父项目或者子项目pom文件中,引入包含新的sl4j-api在内的sl4j三件套

2、而在父项目或者子项目pom文件中,
引入包含新的sl4j-api在内的sl4j三件套之后。
不管子项目的依赖中有没有指定sl4j三件套,控制台都无法正常输出日志。

而且上述的依赖冲突在Maven Helper中是看不到的,将被隐藏,
可能工具以为不会冲突,实际上不是。

最终经过多次试验得出的解决方案是:
1、在父项目的pom文件中排除掉slf4j-api,也就是加上:

                  <exclusion>
                        <artifactId>slf4j-apiartifactId>
                        <groupId>org.slf4jgroupId>
                    exclusion>

2、父项目的pom文件中:
slf4j-apislf4j-reload4j(本身依赖了slf4j-api)都不能引入。
只需要引入log4j-core一项就能解决前面说的sl4j报错的问题。
并且不会影响springboot打印日志。

            <dependency>
                <groupId>org.apache.logging.log4jgroupId>
                <artifactId>log4j-coreartifactId>
               <version>${log4j-core.version}version>
            dependency>

4、Dependency not found

关于父项目的pom文件中,我加入上述的sl4j依赖,爆红无法下载,重启IDEA也没办法。

始终提示Dependency 'xx.xx' not found

最后我的解决办法是:
1、先将完整的依赖,加到子项目的pom文件中,父项目不加依赖。
2、刷新maven,子项目下载依赖成功后,maven仓库文件夹里就有这个包了。
3、移除子项目依赖中的版本号,像前面一样把依赖放到父项目的dependencyManagement中管理版本。

无报错启动的SpringBoot依赖

解决掉上面的所有问题后:
项目终于没问题了(哭死……)

父项目管理依赖:

    <properties>
        <maven.compiler.source>11maven.compiler.source>
        <maven.compiler.target>11maven.compiler.target>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

        <junit.version>4.13.2junit.version>
        <lombok.version>1.18.24lombok.version>
        <spring.cloud.version>2021.0.4spring.cloud.version>
        <spring.boot.version>2.6.11spring.boot.version>
        <spring.boot-web.version>2.6.11spring.boot-web.version>
        <mybatis-plus.version>3.5.0mybatis-plus.version>
        <mybatis-plus-boot-starter.version>3.5.0mybatis-plus-boot-starter.version>
        <jedis.version>4.3.1jedis.version>
        <mysql.version>8.0.25mysql.version>
        <slf4j-api.version>2.0.5slf4j-api.version>
        <slf4j-reload4j.version>2.0.5slf4j-reload4j.version>
        <log4j-core.version>2.19.0log4j-core.version>
    properties>

    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>${lombok.version}version>
            dependency>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>2021.0.4version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
                <version>${spring.boot-web.version}version>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>${mysql.version}version>
            dependency>
            
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plusartifactId>
                <version>${mybatis-plus.version}version>
            dependency>
            
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-boot-starterartifactId>
                <version>${mybatis-plus-boot-starter.version}version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-apiartifactId>
                        <groupId>org.slf4jgroupId>
                    exclusion>
                exclusions>
            dependency>
            
            <dependency>
                <groupId>redis.clientsgroupId>
                <artifactId>jedisartifactId>
                <version>${jedis.version}version>
            dependency>











            <dependency>
                <groupId>org.apache.logging.log4jgroupId>
                <artifactId>log4j-coreartifactId>
                <version>${log4j-core.version}version>
            dependency>
        dependencies>
    dependencyManagement>

子项目 cat-auth 中的依赖:

    <properties>
        <maven.compiler.source>11maven.compiler.source>
        <maven.compiler.target>11maven.compiler.target>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plusartifactId>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
    dependencies>

OpenJDK11手动生成jre文件夹

先下载一个JDK11,因为JDK11初始状态是没有JRE的。
然后在JDK11的/bin目录下,打开powershell或者管理员终端,执行:

./jlink --module-path jmods --add-modules java.desktop --output jre

与Linux下生成jre文件夹一样,生成的jre同样在bin下面:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第13张图片
与之前部署Kafka中部署JDK11一样,把jre文件夹挪到与bin同级。
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第14张图片

IDEA中需要指定JDK的地方

Maven下: 除了指定mavne目录外,还需要指定JDK

【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第15张图片
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第16张图片
为项目模块指定JDK:
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第17张图片
【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第18张图片
为每个子项目指定JDK:

【框架学习(5)-- 引入SpringCloud依赖和解决常见问题】_第19张图片
如果指定子项目JDK出现JDK11自己变回JDK1.8的情况,可以尝试先手动清理掉每一个项目的maven包(clean),刷新Maven或者清除缓存重启IDEA。

你可能感兴趣的:(框架整合学习,spring,cloud,学习,java)