Skip to content

Commit 9370c1e

Browse files
Thomas Darimontodrotbohm
Thomas Darimont
authored andcommitted
DATAMONGO-843 - Improvements in auditing configuration.
Repositories now declare a fallback MappingContext in case none is configured explicitly to make sure @EnableMongoAuditing also works without an explicit MappingContext bean defined. AuditingEntityListener is now referring to the IsNewAwareAuditingHandler via an intermediate ObjectFactory to prevent the downstream dependencies from being instantiated eagerly at listener init time. This is to prevent circular initialization dependencies as Spring accesses ApplicationEventListener beans very early in the container lifecycle to check whether they might be interested in a certain even and just dropped immediately afterwards. Changed BeanNames.MAPPING_CONTEXT constant to mongoMappingContext to let the XML configuration be consistent with AbstractMongoConfiguration.mongoMappingContext().
1 parent 2839e94 commit 9370c1e

15 files changed

+230
-83
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 the original author or authors.
2+
* Copyright 2011-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,13 +24,14 @@
2424
*/
2525
public abstract class BeanNames {
2626

27-
static final String MAPPING_CONTEXT = "mappingContext";
28-
static final String INDEX_HELPER = "indexCreationHelper";
29-
static final String MONGO = "mongo";
30-
static final String DB_FACTORY = "mongoDbFactory";
31-
static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener";
32-
static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory";
27+
public static final String MAPPING_CONTEXT_BEAN_NAME = "mongoMappingContext";
28+
29+
static final String INDEX_HELPER_BEAN_NAME = "indexCreationHelper";
30+
static final String MONGO_BEAN_NAME = "mongo";
31+
static final String DB_FACTORY_BEAN_NAME = "mongoDbFactory";
32+
static final String VALIDATING_EVENT_LISTENER_BEAN_NAME = "validatingMongoEventListener";
33+
static final String IS_NEW_STRATEGY_FACTORY_BEAN_NAME = "isNewStrategyFactory";
3334
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
34-
static final String MONGO_TEMPLATE = "mongoTemplate";
35-
static final String GRID_FS_TEMPLATE = "gridFsTemplate";
35+
static final String MONGO_TEMPLATE_BEAN_NAME = "mongoTemplate";
36+
static final String GRID_FS_TEMPLATE_BEAN_NAME = "gridFsTemplate";
3637
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected String resolveId(Element element, AbstractBeanDefinition definition, P
4343
throws BeanDefinitionStoreException {
4444

4545
String id = super.resolveId(element, definition, parserContext);
46-
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE;
46+
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME;
4747
}
4848

4949
/*
@@ -64,7 +64,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
6464
if (StringUtils.hasText(dbFactoryRef)) {
6565
gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef);
6666
} else {
67-
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
67+
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
6868
}
6969

7070
if (StringUtils.hasText(converterRef)) {
@@ -77,7 +77,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
7777
gridFsTemplateBuilder.addConstructorArgValue(bucket);
7878
}
7979

80-
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE)
80+
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE_BEAN_NAME)
8181
.getBeanDefinition();
8282
}
8383
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java

+12-10
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
8686
BeanDefinitionRegistry registry = parserContext.getRegistry();
8787

8888
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
89-
id = StringUtils.hasText(id) ? id : "mappingConverter";
89+
id = StringUtils.hasText(id) ? id : DEFAULT_CONVERTER_BEAN_NAME;
9090

9191
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element));
9292

@@ -98,7 +98,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
9898
// Need a reference to a Mongo instance
9999
String dbFactoryRef = element.getAttribute("db-factory-ref");
100100
if (!StringUtils.hasText(dbFactoryRef)) {
101-
dbFactoryRef = DB_FACTORY;
101+
dbFactoryRef = DB_FACTORY_BEAN_NAME;
102102
}
103103

104104
// Converter
@@ -116,10 +116,10 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
116116
}
117117

118118
try {
119-
registry.getBeanDefinition(INDEX_HELPER);
119+
registry.getBeanDefinition(INDEX_HELPER_BEAN_NAME);
120120
} catch (NoSuchBeanDefinitionException ignored) {
121121
if (!StringUtils.hasText(dbFactoryRef)) {
122-
dbFactoryRef = DB_FACTORY;
122+
dbFactoryRef = DB_FACTORY_BEAN_NAME;
123123
}
124124
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
125125
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
@@ -128,14 +128,14 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
128128
indexHelperBuilder.addDependsOn(ctxRef);
129129

130130
parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(),
131-
INDEX_HELPER));
131+
INDEX_HELPER_BEAN_NAME));
132132
}
133133

134134
BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
135135

136136
if (validatingMongoEventListener != null) {
137137
parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener,
138-
VALIDATING_EVENT_LISTENER));
138+
VALIDATING_EVENT_LISTENER_BEAN_NAME));
139139
}
140140

141141
parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id));
@@ -180,7 +180,7 @@ private RuntimeBeanReference getValidator(Object source, ParserContext parserCon
180180
return new RuntimeBeanReference(validatorName);
181181
}
182182

183-
static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
183+
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
184184
BeanDefinition conversionsDefinition, String converterId) {
185185

186186
String ctxRef = element.getAttribute("mapping-context-ref");
@@ -215,7 +215,8 @@ static String potentiallyCreateMappingContext(Element element, ParserContext par
215215
CamelCaseAbbreviatingFieldNamingStrategy.class));
216216
}
217217

218-
ctxRef = converterId + "." + MAPPING_CONTEXT;
218+
ctxRef = converterId == null || DEFAULT_CONVERTER_BEAN_NAME.equals(converterId) ? MAPPING_CONTEXT_BEAN_NAME
219+
: converterId + "." + MAPPING_CONTEXT_BEAN_NAME;
219220

220221
parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef));
221222
return ctxRef;
@@ -310,9 +311,10 @@ public static String createIsNewStrategyFactoryBeanDefinition(String mappingCont
310311
mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef);
311312

312313
BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context);
313-
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, IS_NEW_STRATEGY_FACTORY));
314+
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder,
315+
IS_NEW_STRATEGY_FACTORY_BEAN_NAME));
314316

315-
return IS_NEW_STRATEGY_FACTORY;
317+
return IS_NEW_STRATEGY_FACTORY_BEAN_NAME;
316318
}
317319

318320
/**

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012 the original author or authors.
2+
* Copyright 2012-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@
1515
*/
1616
package org.springframework.data.mongodb.config;
1717

18-
import org.springframework.beans.factory.config.BeanDefinition;
18+
import static org.springframework.data.config.ParsingUtils.*;
19+
import static org.springframework.data.mongodb.config.BeanNames.*;
20+
import static org.springframework.data.mongodb.config.MappingMongoConverterParser.*;
21+
1922
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2023
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2124
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
@@ -60,21 +63,23 @@ protected void doParse(Element element, ParserContext parserContext, BeanDefinit
6063

6164
BeanDefinitionRegistry registry = parserContext.getRegistry();
6265

63-
if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) {
66+
String isNewStrategyFactoryName = IS_NEW_STRATEGY_FACTORY_BEAN_NAME;
67+
String mappingContextName = MAPPING_CONTEXT_BEAN_NAME;
6468

65-
String mappingContextName = BeanNames.MAPPING_CONTEXT;
69+
if (!registry.containsBeanDefinition(isNewStrategyFactoryName)) {
6670

67-
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT)) {
68-
mappingContextName = MappingMongoConverterParser.potentiallyCreateMappingContext(element, parserContext, null,
69-
BeanNames.DEFAULT_CONVERTER_BEAN_NAME);
71+
if (!registry.containsBeanDefinition(mappingContextName)) {
72+
mappingContextName = potentiallyCreateMappingContext(element, parserContext, null, null);
7073
}
7174

72-
MappingMongoConverterParser.createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element);
75+
isNewStrategyFactoryName = createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element);
7376
}
7477

75-
BeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(BeanNames.IS_NEW_STRATEGY_FACTORY);
76-
BeanDefinition handlerBeanDefinition = parser.parse(element, parserContext);
78+
IsNewAwareAuditingHandlerBeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(
79+
isNewStrategyFactoryName);
80+
parser.parse(element, parserContext);
7781

78-
builder.addConstructorArgValue(handlerBeanDefinition);
82+
builder.addConstructorArgValue(getObjectFactoryBeanDefinition(parser.getResolvedBeanName(),
83+
parserContext.extractSource(element)));
7984
}
8085
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java

+31-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2013-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,13 +18,15 @@
1818
import java.lang.annotation.Annotation;
1919

2020
import org.springframework.beans.factory.config.BeanDefinition;
21+
import org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean;
22+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2123
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2224
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2325
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
2426
import org.springframework.core.type.AnnotationMetadata;
2527
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
26-
import org.springframework.data.auditing.config.AnnotationAuditingConfiguration;
2728
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
29+
import org.springframework.data.auditing.config.AuditingConfiguration;
2830
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
2931
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
3032
import org.springframework.data.support.IsNewStrategyFactory;
@@ -47,6 +49,15 @@ protected Class<? extends Annotation> getAnnotation() {
4749
return EnableMongoAuditing.class;
4850
}
4951

52+
/*
53+
* (non-Javadoc)
54+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
55+
*/
56+
@Override
57+
protected String getAuditingHandlerBeanName() {
58+
return "mongoAuditingHandler";
59+
}
60+
5061
/*
5162
* (non-Javadoc)
5263
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
@@ -63,16 +74,16 @@ public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanD
6374

6475
/*
6576
* (non-Javadoc)
66-
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AnnotationAuditingConfiguration)
77+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
6778
*/
6879
@Override
69-
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AnnotationAuditingConfiguration configuration) {
80+
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
7081

71-
Assert.notNull(configuration, "AnnotationAuditingConfiguration must not be null!");
82+
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
7283

73-
return configureDefaultAuditHandlerAttributes(configuration,
74-
BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class)).addConstructorArgReference(
75-
BeanNames.IS_NEW_STRATEGY_FACTORY);
84+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
85+
builder.addConstructorArgReference(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME);
86+
return configureDefaultAuditHandlerAttributes(configuration, builder);
7687
}
7788

7889
/*
@@ -86,8 +97,15 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
8697
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
8798
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
8899

89-
registerInfrastructureBeanWithId(BeanDefinitionBuilder.rootBeanDefinition(AuditingEventListener.class)
90-
.addConstructorArgValue(auditingHandlerDefinition).getRawBeanDefinition(),
100+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ObjectFactoryCreatingFactoryBean.class);
101+
builder.addPropertyValue("targetBeanName", getAuditingHandlerBeanName());
102+
builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
103+
104+
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
105+
.rootBeanDefinition(AuditingEventListener.class);
106+
listenerBeanDefinitionBuilder.addConstructorArgValue(builder.getBeanDefinition());
107+
108+
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
91109
AuditingEventListener.class.getName(), registry);
92110
}
93111

@@ -96,10 +114,10 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
96114
*/
97115
private void registerIsNewStrategyFactoryIfNecessary(BeanDefinitionRegistry registry) {
98116

99-
if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) {
100-
registry.registerBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY,
117+
if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME)) {
118+
registry.registerBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME,
101119
BeanDefinitionBuilder.rootBeanDefinition(MappingContextIsNewStrategyFactory.class)
102-
.addConstructorArgReference(BeanNames.MAPPING_CONTEXT).getBeanDefinition());
120+
.addConstructorArgReference(BeanNames.MAPPING_CONTEXT_BEAN_NAME).getBeanDefinition());
103121
}
104122
}
105123
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 by the original author(s).
2+
* Copyright 2011-2014 by the original author(s).
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ protected String resolveId(Element element, AbstractBeanDefinition definition, P
5454
throws BeanDefinitionStoreException {
5555

5656
String id = super.resolveId(element, definition, parserContext);
57-
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY;
57+
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME;
5858
}
5959

6060
/*
@@ -103,7 +103,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
103103
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
104104
parserContext.registerBeanComponent(component);
105105

106-
return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY)
106+
return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY_BEAN_NAME)
107107
.getBeanDefinition();
108108
}
109109

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2012 the original author or authors.
2+
* Copyright 2011-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
5858
MongoParsingUtils.parseMongoOptions(element, builder);
5959
MongoParsingUtils.parseReplicaSet(element, builder);
6060

61-
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO;
61+
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
6262

6363
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
6464

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 the original author or authors.
2+
* Copyright 2011-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535
* {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s.
3636
*
3737
* @author Martin Baumgartner
38+
* @author Oliver Gierke
3839
*/
3940
class MongoTemplateParser extends AbstractBeanDefinitionParser {
4041

@@ -47,7 +48,7 @@ protected String resolveId(Element element, AbstractBeanDefinition definition, P
4748
throws BeanDefinitionStoreException {
4849

4950
String id = super.resolveId(element, definition, parserContext);
50-
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE;
51+
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME;
5152
}
5253

5354
/*
@@ -68,7 +69,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
6869
if (StringUtils.hasText(dbFactoryRef)) {
6970
mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef);
7071
} else {
71-
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
72+
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
7273
}
7374

7475
if (StringUtils.hasText(converterRef)) {
@@ -80,7 +81,7 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
8081
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
8182
parserContext.registerBeanComponent(component);
8283

83-
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, BeanNames.MONGO_TEMPLATE)
84-
.getBeanDefinition();
84+
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder,
85+
BeanNames.MONGO_TEMPLATE_BEAN_NAME).getBeanDefinition();
8586
}
8687
}

0 commit comments

Comments
 (0)