使用 application.yml 中的属性在来自 spring data mongodb 的 @Document 中注入集合名称

问题描述 投票:0回答:3

我想使用 application.yml 中的属性从 Mongo 集合中命名我的集合名称。

例如,如果我得到那个文件: 应用程序.yml

spring.data.mongodb.person-collection: character

我想在那个实体中注入那个属性:

@Document(collection = "@Value('spring.data.mongodb.person-collection')")
public class PersonEntity {
    ...
}

我想使用该属性,因为我有很多使用相同数据库的环境。我想根据环境的功能隔离一些集合。

你知道我该如何解决吗?

(我尝试使用 SpEL,但无法解决该问题)。

编辑:

我试图通过使用另一个 bean 来注入我的属性来解决问题

@Component
public class PersonRepositoryCustom {

private static String collectionName;

/**
 * @return the collectionName
 */
public static String getCollectionName() {
    return collectionName;
}

@Value("${spring.data.mongodb.person-collection:person}")
public void setCollectionName(String collectionNameVariable) {
    collectionName = collectionNameVariable;
}

}

所以我通过以下方式更改了文档注释:

@Document(collection = "#{@T(persistence.mongodb.repositories.PersonRepositoryCustom).getCollectionName()}")

所以我收到了那个消息

Caused by: org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lparen(()'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:135) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:61) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:33) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpressions(TemplateAwareExpressionParser.java:121) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.expression.common.TemplateAwareExpressionParser.parseTemplate(TemplateAwareExpressionParser.java:62) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:49) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.detectExpression(BasicMongoPersistentEntity.java:255) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.<init>(BasicMongoPersistentEntity.java:80) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:90) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:39) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:366) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:248) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:191) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:85) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:73) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getEntityInformation(MongoRepositoryFactory.java:149) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getTargetRepository(MongoRepositoryFactory.java:123) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean.afterPropertiesSet(MongoRepositoryFactoryBean.java:119) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
... 22 more

我尝试了另一种方式,直接使用 bean :

package persistence.mongodb.repositories;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PersonRepositoryCustom {

private static String collectionName;

/**
 * @return the collectionName
 */
public String getCollectionName() {
    return collectionName;
}

@Value("${spring.data.mongodb.person-collection:person}")
public void setCollectionName(String collectionNameVariable) {
    collectionName = collectionNameVariable;
}

}

所以我用以下内容更新了我的文档注释:

@Document(collection = "#{@personRepositoryCustom.getCollectionName()}")

我收到了那条消息:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean  'personRepositoryCustom'
java spring mongodb spring-boot spring-data-mongodb
3个回答
2
投票

我终于找到了解决这个问题的方法,使用@Valijon 给出的部分答案和 stackoverflow 上另一篇文章的另一部分答案

package persistence.mongodb.repositories;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PersonRepositoryCustom {

private static String collectionName;

/**
 * @return the collectionName
 */
public static String getCollectionName() {
    return collectionName;
}

@Value("${spring.data.mongodb.person-collection:person}")
public void setCollectionName(String collectionNameVariable) {
    collectionName = collectionNameVariable;
}

}

@Document(collection = "#{T(mongodb.repositories.PersonRepositoryCustom).getCollectionName() }")
public class PersonEntity { ... }

0
投票

您可以使用 SpEL(有效)

  1. 使用
    @Component
    类获得
    @Value
    并使用SpEL

@Component
public class CustomMongoCollection {

    @Value("spring.data.mongodb.person-collection")
    private String person;

    public void getCollectionName(String coll) {
        if ("person".equals(coll)) {
            return person;
        } else {
            //setup here
        }
    }
}

@Document(collection = "#{customMongoCollection.getCollectionName('person')}")
public class PersonEntity {

}

注: 我在单元测试的时候遇到了问题


  1. 使用'T'运算符

    特殊的“T”运算符可用于指定 java.lang.Class(“类型”)的实例。也使用此运算符调用静态方法。 StandardEvaluationContext 使用 TypeLocator 来查找类型,而 StandardTypeLocator(可以替换)是在理解 java.lang 包的情况下构建的。这意味着 T() 对 java.lang 中类型的引用不需要完全限定,但所有其他类型引用必须是。

https://docs.spring.io/spring/docs/3.0.x/reference/expressions.html

#{T(your.package.CustomMongoCollection).getCollectionName('person')}

注意:现在CustomMongoCollection.getCollectionName是

static
方法。


0
投票

在SpEL中,使用bean,一定要在bean名字前加上

@
。这是相关的,因为如果缺少它,SpEL 将查找具有该名称的属性而不是 bean。在弄清楚这一点之前,我浪费了一些时间。 @Valijon 和@user3460409 的答案接近正确,但都没有谈论
@
的使用,而是谈论
T
运算符。

创建一个类,它有一个用

@Value
注释注释的字段,从文件中获取属性。应该为这个类创建一个 bean,在这个例子中我使用
@Component
来自动生成 bean。

@Component
class Constants {
    @Value("${spring.data.mongodb.person-collection}")
    private String personCollectionName;

    public String getPersonCollectionName() {
        return this.personCollectionName;
    }
}

接下来,在您实际的实体类中,使用 SpEL(Spring Expression Language)从创建的类的 bean 中获取值(默认情况下,bean 名称是小写的类名)。

@Document(collection = "#{@constants.personCollectionName}")
public class PersonEntity {
    ...
}

再次注意豆名前的

@

© www.soinside.com 2019 - 2024. All rights reserved.