首页 > 解决方案 > 使用 application.yml 中的属性从 spring data mongodb 中注入 @Document 中的集合名称

问题描述

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

例如,如果我得到那个文件:application.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'

标签: javaspringmongodbspring-bootspring-data-mongodb

解决方案


您可以使用 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 包的情况下构建的。这意味着对 java.lang 中类型的 T() 引用不需要完全限定,但所有其他类型引用必须是完全限定的。

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

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

注意:现在 CustomMongoCollection.getCollectionName 是static方法。


推荐阅读