42
42
import org .springframework .util .ClassUtils ;
43
43
44
44
/**
45
- * An {@link EntityInstantiator} that can generate byte code to speed-up dynamic object instantiation.
46
- * <p>
47
- * Uses the {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an instance of the entity by
48
- * dynamically generating factory methods with appropriate constructor invocations via ASM.
49
- * <p>
50
- * If we cannot generate byte code for a type, we gracefully fall-back to the {@link ReflectionEntityInstantiator}.
45
+ * An {@link EntityInstantiator} that can generate byte code to speed-up dynamic object instantiation. Uses the
46
+ * {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an instance of the entity by dynamically
47
+ * generating factory methods with appropriate constructor invocations via ASM. If we cannot generate byte code for a
48
+ * type, we gracefully fall-back to the {@link ReflectionEntityInstantiator}.
51
49
*
52
50
* @author Thomas Darimont
51
+ * @author Oliver Gierke
53
52
* @since 1.10
54
53
*/
55
54
public enum BytecodeGeneratingEntityInstantiator implements EntityInstantiator {
@@ -68,15 +67,13 @@ public enum BytecodeGeneratingEntityInstantiator implements EntityInstantiator {
68
67
public <T , E extends PersistentEntity <? extends T , P >, P extends PersistentProperty <P >> T createInstance (E entity ,
69
68
ParameterValueProvider <P > provider ) {
70
69
71
- EntityInstantiator ei = this .entityInstantiators .get (entity .getTypeInformation ());
70
+ EntityInstantiator instantiator = this .entityInstantiators .get (entity .getTypeInformation ());
72
71
73
- if (ei ! = null ) {
74
- return ei . createInstance (entity , provider );
72
+ if (instantiator = = null ) {
73
+ instantiator = potentiallyCreateAndRegisterEntityInstantiator (entity );
75
74
}
76
75
77
- ei = potentiallyCreateAndRegisterEntityInstantiator (entity );
78
-
79
- return ei .createInstance (entity , provider );
76
+ return instantiator .createInstance (entity , provider );
80
77
}
81
78
82
79
/**
@@ -86,20 +83,20 @@ public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentPrope
86
83
private synchronized EntityInstantiator potentiallyCreateAndRegisterEntityInstantiator (PersistentEntity <?, ?> entity ) {
87
84
88
85
Map <TypeInformation <?>, EntityInstantiator > map = this .entityInstantiators ;
86
+ EntityInstantiator instantiator = map .get (entity .getTypeInformation ());
89
87
90
- EntityInstantiator ei = map .get (entity .getTypeInformation ());
91
- if (ei != null ) {
92
- return ei ;
88
+ if (instantiator != null ) {
89
+ return instantiator ;
93
90
}
94
91
95
- ei = createEntityInstantiator (entity );
92
+ instantiator = createEntityInstantiator (entity );
96
93
97
94
map = new HashMap <TypeInformation <?>, EntityInstantiator >(map );
98
- map .put (entity .getTypeInformation (), ei );
95
+ map .put (entity .getTypeInformation (), instantiator );
99
96
100
97
this .entityInstantiators = map ;
101
98
102
- return ei ;
99
+ return instantiator ;
103
100
}
104
101
105
102
/**
@@ -194,7 +191,10 @@ public Class<?> loadClass(String name, byte[] bytes) {
194
191
}
195
192
196
193
/**
194
+ * Adapter to forward an invocation of the {@link EntityInstantiator} API to an {@link ObjectInstantiator}.
195
+ *
197
196
* @author Thomas Darimont
197
+ * @author Oliver Gierke
198
198
*/
199
199
private static class EntityInstantiatorAdapter implements EntityInstantiator {
200
200
@@ -203,18 +203,25 @@ private static class EntityInstantiatorAdapter implements EntityInstantiator {
203
203
private final ObjectInstantiator instantiator ;
204
204
205
205
/**
206
- * @param instantiator
206
+ * Creates a new {@link EntityInstantiatorAdapter} for the given {@link ObjectInstantiator}.
207
+ *
208
+ * @param instantiator must not be {@literal null}.
207
209
*/
208
210
public EntityInstantiatorAdapter (ObjectInstantiator instantiator ) {
209
211
this .instantiator = instantiator ;
210
212
}
211
213
214
+ /*
215
+ * (non-Javadoc)
216
+ * @see org.springframework.data.convert.EntityInstantiator#createInstance(org.springframework.data.mapping.PersistentEntity, org.springframework.data.mapping.model.ParameterValueProvider)
217
+ */
212
218
@ Override
213
219
@ SuppressWarnings ("unchecked" )
214
220
public <T , E extends PersistentEntity <? extends T , P >, P extends PersistentProperty <P >> T createInstance (E entity ,
215
221
ParameterValueProvider <P > provider ) {
216
222
217
- Object [] params = extractInvocationArguments (provider , entity .getPersistenceConstructor ());
223
+ Object [] params = extractInvocationArguments (entity .getPersistenceConstructor (), provider );
224
+
218
225
try {
219
226
return (T ) instantiator .newInstance (params );
220
227
} catch (Exception e ) {
@@ -223,19 +230,22 @@ public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentPrope
223
230
}
224
231
225
232
/**
226
- * @param provider
227
- * @param prefCtor
233
+ * Extracts the arguments required to invoce the given constructor from the given {@link ParameterValueProvider}.
234
+ *
235
+ * @param constructor can be {@literal null}.
236
+ * @param provider can be {@literal null}.
228
237
* @return
229
238
*/
230
239
private <P extends PersistentProperty <P >, T > Object [] extractInvocationArguments (
231
- ParameterValueProvider < P > provider , PreferredConstructor <? extends T , P > prefCtor ) {
240
+ PreferredConstructor <? extends T , P > constructor , ParameterValueProvider < P > provider ) {
232
241
233
- if (provider == null || prefCtor == null || !prefCtor .hasParameters ()) {
242
+ if (provider == null || constructor == null || !constructor .hasParameters ()) {
234
243
return EMPTY_ARRAY ;
235
244
}
236
245
237
246
List <Object > params = new ArrayList <Object >();
238
- for (Parameter <?, P > parameter : prefCtor .getParameters ()) {
247
+
248
+ for (Parameter <?, P > parameter : constructor .getParameters ()) {
239
249
params .add (provider .getParameterValue (parameter ));
240
250
}
241
251
0 commit comments