java - 使用 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
它是我的服务和库的父包。
我的问题如下:
如果我包含库的源代码,我的 bean 会被正确拾取并初始化。之后,Spring
BeanPostProcessor
正确地调用了扩展类,从而调用了我自己的方法。对此的调用如下所示:private void doPostProcess(AnnotationType annotationType, Method method, Object bean) { annotationType = postProcessAnnotation(annotationType, method); ... Other stuff in Spring lib }
如果我包含我自己的库的
.jar
文件,我的库配置中的 bean 未初始化,尽管配置本身已初始化。
为什么会发生这种情况?我扫描带有或不带有源的相同包,并且它自己期望带来的服务的唯一库与 Spring 无关。
解决方案
问题如下:
@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。
推荐阅读
- syntax-error - Uncaught SyntaxError: missing ) 在使用数据标签时在参数列表之后
- node.js - 比较来自 db 的哈希(登录)
- javascript - 根据半径向用户显示附近的位置
- javascript - 如何在不刷新整个页面的情况下从 javascript 为用户提供浏览器的本机身份验证对话框?
- node.js - 如何对多个实时 Firebase 数据库使用 onCreate 命令?
- bash - 如何让 bash 高效读取包含 NUL 字节的数据?
- laravel - Laravel 自定义表格验证
- python - discord.py:在发布禁令之前,我如何检查用户是否在服务器中?
- javascript - 如何使用在 javascript 中构造的列表遍历 html 中的项目列表?
- linux - 如何使用算术扩展和wc在bash脚本中将单词数与文件的字符数相除