1
1
/*
2
- * Copyright 2002-2010 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
25
25
import org .aopalliance .intercept .MethodInvocation ;
26
26
27
27
import org .springframework .aop .framework .ProxyFactory ;
28
+ import org .springframework .beans .SimpleTypeConverter ;
29
+ import org .springframework .beans .TypeConverter ;
30
+ import org .springframework .beans .TypeMismatchException ;
28
31
import org .springframework .beans .factory .BeanClassLoaderAware ;
32
+ import org .springframework .beans .factory .BeanFactory ;
33
+ import org .springframework .beans .factory .BeanFactoryAware ;
29
34
import org .springframework .beans .factory .FactoryBean ;
35
+ import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
30
36
import org .springframework .util .ClassUtils ;
31
37
32
38
/**
61
67
* @see #setCache
62
68
* @see JndiObjectTargetSource
63
69
*/
64
- public class JndiObjectFactoryBean extends JndiObjectLocator implements FactoryBean <Object >, BeanClassLoaderAware {
70
+ public class JndiObjectFactoryBean extends JndiObjectLocator
71
+ implements FactoryBean <Object >, BeanFactoryAware , BeanClassLoaderAware {
65
72
66
- private Class [] proxyInterfaces ;
73
+ private Class <?> [] proxyInterfaces ;
67
74
68
75
private boolean lookupOnStartup = true ;
69
76
@@ -73,6 +80,8 @@ public class JndiObjectFactoryBean extends JndiObjectLocator implements FactoryB
73
80
74
81
private Object defaultObject ;
75
82
83
+ private ConfigurableBeanFactory beanFactory ;
84
+
76
85
private ClassLoader beanClassLoader = ClassUtils .getDefaultClassLoader ();
77
86
78
87
private Object jndiObject ;
@@ -87,8 +96,8 @@ public class JndiObjectFactoryBean extends JndiObjectLocator implements FactoryB
87
96
* @see #setLookupOnStartup
88
97
* @see #setCache
89
98
*/
90
- public void setProxyInterface (Class proxyInterface ) {
91
- this .proxyInterfaces = new Class [] {proxyInterface };
99
+ public void setProxyInterface (Class <?> proxyInterface ) {
100
+ this .proxyInterfaces = new Class <?> [] {proxyInterface };
92
101
}
93
102
94
103
/**
@@ -100,7 +109,7 @@ public void setProxyInterface(Class proxyInterface) {
100
109
* @see #setLookupOnStartup
101
110
* @see #setCache
102
111
*/
103
- public void setProxyInterfaces (Class [] proxyInterfaces ) {
112
+ public void setProxyInterfaces (Class <?>... proxyInterfaces ) {
104
113
this .proxyInterfaces = proxyInterfaces ;
105
114
}
106
115
@@ -149,12 +158,26 @@ public void setExposeAccessContext(boolean exposeAccessContext) {
149
158
* It is typically used for literal values in scenarios where the JNDI environment
150
159
* might define specific config settings but those are not required to be present.
151
160
* <p>Note: This is only supported for lookup on startup.
161
+ * If specified together with {@link #setExpectedType}, the specified value
162
+ * needs to be either of that type or convertible to it.
152
163
* @see #setLookupOnStartup
164
+ * @see ConfigurableBeanFactory#getTypeConverter()
165
+ * @see SimpleTypeConverter
153
166
*/
154
167
public void setDefaultObject (Object defaultObject ) {
155
168
this .defaultObject = defaultObject ;
156
169
}
157
170
171
+ @ Override
172
+ public void setBeanFactory (BeanFactory beanFactory ) {
173
+ if (beanFactory instanceof ConfigurableBeanFactory ) {
174
+ // Just optional - for getting a specifically configured TypeConverter if needed.
175
+ // We'll simply fall back to a SimpleTypeConverter if no specific one available.
176
+ this .beanFactory = (ConfigurableBeanFactory ) beanFactory ;
177
+ }
178
+ }
179
+
180
+ @ Override
158
181
public void setBeanClassLoader (ClassLoader classLoader ) {
159
182
this .beanClassLoader = classLoader ;
160
183
}
@@ -179,9 +202,16 @@ public void afterPropertiesSet() throws IllegalArgumentException, NamingExceptio
179
202
else {
180
203
if (this .defaultObject != null && getExpectedType () != null &&
181
204
!getExpectedType ().isInstance (this .defaultObject )) {
182
- throw new IllegalArgumentException ("Default object [" + this .defaultObject +
183
- "] of type [" + this .defaultObject .getClass ().getName () +
184
- "] is not of expected type [" + getExpectedType ().getName () + "]" );
205
+ TypeConverter converter = (this .beanFactory != null ?
206
+ this .beanFactory .getTypeConverter () : new SimpleTypeConverter ());
207
+ try {
208
+ this .defaultObject = converter .convertIfNecessary (this .defaultObject , getExpectedType ());
209
+ }
210
+ catch (TypeMismatchException ex ) {
211
+ throw new IllegalArgumentException ("Default object [" + this .defaultObject + "] of type [" +
212
+ this .defaultObject .getClass ().getName () + "] is not of expected type [" +
213
+ getExpectedType ().getName () + "] and cannot be converted either" , ex );
214
+ }
185
215
}
186
216
// Locate specified JNDI object.
187
217
this .jndiObject = lookupWithFallback ();
@@ -263,7 +293,7 @@ public boolean isSingleton() {
263
293
* @return the merged interface as Class
264
294
* @see java.lang.reflect.Proxy#getProxyClass
265
295
*/
266
- protected Class createCompositeInterface (Class [] interfaces ) {
296
+ protected Class <?> createCompositeInterface (Class <?> [] interfaces ) {
267
297
return ClassUtils .createCompositeInterface (interfaces , this .beanClassLoader );
268
298
}
269
299
@@ -290,13 +320,13 @@ private static Object createJndiObjectProxy(JndiObjectFactoryBean jof) throws Na
290
320
proxyFactory .setInterfaces (jof .proxyInterfaces );
291
321
}
292
322
else {
293
- Class targetClass = targetSource .getTargetClass ();
323
+ Class <?> targetClass = targetSource .getTargetClass ();
294
324
if (targetClass == null ) {
295
325
throw new IllegalStateException (
296
326
"Cannot deactivate 'lookupOnStartup' without specifying a 'proxyInterface' or 'expectedType'" );
297
327
}
298
- Class [] ifcs = ClassUtils .getAllInterfacesForClass (targetClass , jof .beanClassLoader );
299
- for (Class ifc : ifcs ) {
328
+ Class <?> [] ifcs = ClassUtils .getAllInterfacesForClass (targetClass , jof .beanClassLoader );
329
+ for (Class <?> ifc : ifcs ) {
300
330
if (Modifier .isPublic (ifc .getModifiers ())) {
301
331
proxyFactory .addInterface (ifc );
302
332
}
0 commit comments