简体   繁体   English

使用 application.yml 中的属性从 spring 数据 mongodb 在 @Document 中注入集合名称

[英]Inject collection name in @Document from spring data mongodb in using a property from application.yml

I'd like to name my collection name from a Mongo Collection in using a property from application.yml.我想使用 application.yml 中的属性从 Mongo 集合中命名我的集合名称。

For instance, if i got that file : application.yml例如,如果我得到那个文件:application.yml

spring.data.mongodb.person-collection: character

And I'd like to inject that property in that Entity:我想在该实体中注入该属性:

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

I'd like to use that property because i've many environment, who use the same database.我想使用该属性,因为我有很多使用相同数据库的环境。 I'd like to isolate some collections in function of the environment.我想根据环境功能隔离一些集合。

Do you have any idea how I can resolve that ?你知道我该如何解决吗?

(I tried with SpEL but I couldn't resolve that problem). (我尝试使用 SpEL,但无法解决该问题)。

Edit :编辑 :

I tried to make a workaround in using another bean to inject my property我试图解决使用另一个 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;
}

}

So I changed my document annotation by :所以我通过以下方式更改了我的文档注释:

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

SO i got that message所以我收到了这条消息

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

I tried it in another way, in using a bean directly :我以另一种方式尝试过,直接使用 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;
}

}

So i updated my document annotation with the following :所以我用以下内容更新了我的文档注释:

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

And i got that message :我收到了这条消息:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean  'personRepositoryCustom'

You may use SpEL (It works)您可以使用 SpEL(它有效)

  1. Use @Component class to get @Value and use SpEL使用@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 {

}

Note: I had problems during unit testing注意:我在单元测试期间遇到了问题


  1. Use 'T' operator使用“T”运算符

    The special 'T' operator can be used to specify an instance of java.lang.Class (the 'type').特殊的“T”运算符可用于指定 java.lang.Class 的实例(“类型”)。 Static methods are invoked using this operator as well.静态方法也使用此运算符调用。 The StandardEvaluationContext uses a TypeLocator to find types and the StandardTypeLocator (which can be replaced) is built with an understanding of the java.lang package. StandardEvaluationContext 使用 TypeLocator 来查找类型,并且 StandardTypeLocator(可以替换)是在了解 java.lang 包的情况下构建的。 This means T() references to types within java.lang do not need to be fully qualified, but all other type references must be.这意味着对 java.lang 中类型的 T() 引用不需要完全限定,但所有其他类型引用必须是。

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

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

Note: Now CustomMongoCollection.getCollectionName is static method.注意:现在 CustomMongoCollection.getCollectionName 是static方法。

I finally found a way to resolve that in using a part of the answer given by @Valijon and another part from another post on stackoverflow我终于找到了一种方法来解决这个问题,即使用@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 { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Boot - 从 application.yml 和 application.properties 注入 - Spring Boot - inject from application.yml and application.properties 根据application.yml的属性注入Spring Boot - Inject with Spring Boot depending on properties from application.yml Spring Boot - 从 application.yml 注入地图 - Spring Boot - inject map from application.yml Spring Boot-从application.yml注入静态映射 - Spring Boot - inject static map from application.yml 如何将 application.yml 中的 map 注入 Spring 引导中的字段? - How to inject a map from application.yml into a field in Spring Boot? spring-boot-starter-data-mongodb-reactive 从 application.yml 设置密钥库密码以使用 X509 进行连接 - spring-boot-starter-data-mongodb-reactive setting keystore password from application.yml for connecting using X509 从 Micronaut 中的 application.yml 访问属性 - Access Property from application.yml in Micronaut 如何从 application.yml 文件注入属性? - How to inject properties from application.yml file? 如何从spring application.yml设置“ max_allowed_pa​​cket”属性 - How to set “max_allowed_packet” property from spring application.yml 是否可以将 application.yml 中的属性解析为具有不同名称的 java 类字段? - Is it possible to parse a property from application.yml to the java class field with a different name?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM