首页 > 解决方案 > 使用 jar 文件而不是源时未初始化 Bean

问题描述

我有一项使用自写库的服务。在库中,我使用了一些 Spring 功能并扩展了一个 bean 后处理器以允许进行一些自定义配置。lib 本身包含 Spring 库作为 gradle 下的编译依赖项。这一切看起来如下:

构建.gradle

buildscript {
    ext {
        springBootVersion = '2.0.3.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'org.stuff.library'
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}


ext {
    springCloudVersion = 'Finchley.RELEASE'
    jacksonVersion = '2.9.6'
    lombokVersion = '1.16.18'
    jooqVersion = '3.11.2'
    flywayVersion = '5.1.3'
}

dependencies {

    compile 'org.aspectj:aspectjweaver'
    compile 'org.springframework:spring-tx'
    compile 'org.springframework.cloud:spring-cloud-stream'
    compile 'org.springframework.cloud:spring-cloud-stream-binder-kafka'
    compile 'org.apache.commons:commons-lang3:3.5'
    compile 'org.javassist:javassist:3.22.0-GA'
    compile "org.flywaydb:flyway-core:${flywayVersion}"

    compileOnly "org.jooq:jooq:${jooqVersion}"
    compileOnly "org.projectlombok:lombok:${lombokVersion}"

    // other testCompile dependencies
}

扩展后处理器的 Bean:

package org.stuff.library.config;

public class AnnotationTypePostProcessor extends AnnotationTypeBeanPostProcessor {

  @Override
  public AnnotationType postProcessAnnotation(AnnotationType original Annotation, Method annotatedMethod) {

  ... do some service-specific stuff
  return super.postProcessAnnotation();
  }
}

这个 bean 被实例化如下:

@Bean(
    name = {SPRING_LIB_BEAN_NAME}
)
public static AnnotationTypeAnnotationBeanPostProcessor annotationTypeAnnotationBeanPostProcessor() {
    return new AnnotationTypePostProcessor();
}

启动时,我发出一个组件扫描,org.stuff它是我的服务和库的父包。

我的问题如下:

  1. 如果我包含库的源代码,我的 bean 会被正确拾取并初始化。之后,SpringBeanPostProcessor正确地调用了扩展类,从而调用了我自己的方法。对此的调用如下所示:

    private void doPostProcess(AnnotationType annotationType, Method method, Object bean) {
    annotationType = postProcessAnnotation(annotationType, method);
    ... Other stuff in Spring lib
    }
    
  2. 如果我包含我自己的库的.jar文件,我的库配置中的 bean 未初始化,尽管配置本身已初始化。

为什么会发生这种情况?我扫描带有或不带有源的相同包,并且它自己期望带来的服务的唯一库与 Spring 无关。

标签: javaspring

解决方案


问题如下:

@Configuration带有要被覆盖的 bean 声明类型的注释的类AnnotationTypeAnnotationBeanPostProcessor没有导入声明 bean 的原始配置类。

出于某种原因,似乎 Spring 要求在按名称给出 bean 时显式设置它以覆盖 bean。我找不到原因。

需要明确的是,解决方案是将包含覆盖 bean 的配置类声明从:

@Configuration
public class SomeConfig() {

@Bean(name = {SPRING_LIB_BEAN_NAME})
public static AnnotationTypeAnnotationBeanPostProcessor annotationTypeAnnotationBeanPostProcessor() {
    return new AnnotationTypePostProcessor();
}

至:

@Configuration
@Import(OriginalConfigurationClassContainingBeanBelow.class)
public class SomeConfig() {

@Bean(name = {SPRING_LIB_BEAN_NAME})
public static AnnotationTypeAnnotationBeanPostProcessor annotationTypeAnnotationBeanPostProcessor() {
    return new AnnotationTypePostProcessor();
}

之后,Spring 总是使用覆盖的 bean。


推荐阅读