我想使用 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'
我终于找到了解决这个问题的方法,使用@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 { ... }
您可以使用 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 {
}
注: 我在单元测试的时候遇到了问题
特殊的“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
方法。
在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 {
...
}
再次注意豆名前的
@
。