SpringBoot 引入第三方ja包中的bean

为什么Spring Boot 项目打包成的 jar ,被其他项目依赖之后,总是报找不到类的错误?

大伙有这样的疑问,就是因为还没搞清楚可执行 jar 和普通 jar 到底有什么区别?

Spring Boot 中默认打包成的 jar 叫做 可执行 jar,这种 jar 不同于普通的 jar
普通的 jar 不可以通过 java -jar xxx.jar 命令执行,普通的 jar 主要是被其他应用依赖,Spring Boot 打成的 jar 可以执行,但是不可以被其他的应用所依赖,即使强制依赖,也无法获取里边的类。
所以,如果要打成一个可以被其他项目依赖的jar包,pom文件里的build模块就不能写成:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>



以下两种写法都是可以的:
方法一:直接使用传统maven打包插件

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
</build>


方法二:直接使用传统maven打包插件

<build>
     <plugins>
         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
             <configuration>
                 <classifier>exec</classifier>
             </configuration>
         </plugin>
     </plugins>
</build>


配置的 classifier 表示可执行 jar 的名字,配置了这个之后,在插件执行 repackage 命令时,就不会给 mvn package 所打成的 jar 重命名了,所以,打包后的 jar 如下:
  
第一个 jar 表示可以被其他项目依赖的 jar ,第二个 jar 则表示一个可执行 jar。




------------------------------------ springboot 引入第三方jar包中定义的bean -------------------------------

springboot工程引入第三方jar包中定义的bean,只需要2步即可:


1、引入的jar包,必须是可以被依赖的包,如果是springboot框架打的jar包,不能使用默认的打包插件直接打包

2、如何把已经引入的依赖中的bean载入容器中呢?
      方法一:比如在jar包定义的一个拦截器,在新的项目中重新载入
        

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
                }
        }


      这里存在一个问题:做了2次bean的载入 (不推荐这个方法)

      方法二:
      SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描!Application类是指SpringBoot项目入口类。

这个类的位置很关键: 如果Application类所在的包为:com.openplat,则只会扫描com.openplat包及其所有子包,如果mapper、service所在包不在com.openplat及其子包下,则不会被扫描。

即, 把Application类放到mapper、service所在包的上级,com.openplat.OpenPlatApplication 

知道这一点非常关键,不知道Spring文档里有没有给出说明,如果不知道还真是无从解决

      所以这里可以使用@SpringBootApplication(scanBasePackages = {"com.ccb","com.example"}),使用其中com.ccb是本地多模块的包的统一前缀,com.example是引用的第三方jar包bean所在的路径,这样springboot就可以扫描到第三方的bean,进行加载,不用在针对第三方jar包中定义的bean重新进行操作,就可以直接使用了

 
 


实例:引入第三方jar包中定义的一个拦截器 interceptor

           

1、新建一个maven项目,定义一个拦截器

/**

  * @Description: 新建一个拦截器
  * @Author: Top
  * @Version: V1.0
  * @Date: 2020/6/11 9:34 上午
  */
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
log.info("preHandle:请求前调用");
//返回 false 则请求中断
return true;
}

@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("postHandle:请求后调用");
}

@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info("afterCompletion:请求调用完成后回调方法,即在视图渲染完成后回调");
}
}

2、注册拦截器到Spring容器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}

3、打包该maven工程为一个可以依赖的jar包

4、在新的项目中引入依赖    

<dependency>

          <groupId>com.example</groupId>
          <artifactId>demo</artifactId>
          <version>0.0.9-SNAPSHOT</version>
</dependency>

5、修改新项目的启动类的注解SpringBootApplication,添加红色部分,使该项目可以扫描到第三方引入jar包中的bean,

@SpringBootApplication(scanBasePackages = {"com.ccb","com.example"})

6、到这里,在新的项目中,引入第三方jar包中的拦截器已经注入到容器中生效,可以进行拦截了。这里有一个要注意的点,如果被引用的jar包中已经做了注册操作(也就是做了第2步的操作),那这里第5步就可以了;如果在原项目中,只是定义了拦截器,没有注册操作(没有进行步骤2的操作),那么在新的系统引入该jar包之后,除了第5步添加扫描,还要进行注册该拦截器,才可以生效。




参考资料:
java - Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖? - 个人文章 - SegmentFault 思否

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值