Skip to content

Commit a5606a6

Browse files
committed
Polishing
1 parent 3cb1cb5 commit a5606a6

File tree

9 files changed

+268
-140
lines changed

9 files changed

+268
-140
lines changed

spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ else if (convertedValue instanceof Map) {
220220
else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
221221
if (firstAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) {
222222
try {
223-
Constructor strCtor = requiredType.getConstructor(String.class);
224-
return (T) BeanUtils.instantiateClass(strCtor, convertedValue);
223+
Constructor<T> strCtor = requiredType.getConstructor(String.class);
224+
return BeanUtils.instantiateClass(strCtor, convertedValue);
225225
}
226226
catch (NoSuchMethodException ex) {
227227
// proceed with field lookup
@@ -331,7 +331,7 @@ private Object attemptToConvertStringToEnum(Class<?> requiredType, String trimme
331331
* @param requiredType the type to find an editor for
332332
* @return the corresponding editor, or {@code null} if none
333333
*/
334-
private PropertyEditor findDefaultEditor(Class requiredType) {
334+
private PropertyEditor findDefaultEditor(Class<?> requiredType) {
335335
PropertyEditor editor = null;
336336
if (requiredType != null) {
337337
// No custom editor -> check BeanWrapperImpl's default editors.
@@ -496,7 +496,7 @@ else if (input.getClass().isArray()) {
496496

497497
@SuppressWarnings("unchecked")
498498
private Collection convertToTypedCollection(
499-
Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
499+
Collection original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) {
500500

501501
if (!Collection.class.isAssignableFrom(requiredType)) {
502502
return original;
@@ -578,7 +578,7 @@ private Collection convertToTypedCollection(
578578

579579
@SuppressWarnings("unchecked")
580580
private Map convertToTypedMap(
581-
Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
581+
Map original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) {
582582

583583
if (!Map.class.isAssignableFrom(requiredType)) {
584584
return original;
@@ -674,7 +674,7 @@ private String buildKeyedPropertyName(String propertyName, Object key) {
674674
null);
675675
}
676676

677-
private boolean canCreateCopy(Class requiredType) {
677+
private boolean canCreateCopy(Class<?> requiredType) {
678678
return (!requiredType.isInterface() && !Modifier.isAbstract(requiredType.getModifiers()) &&
679679
Modifier.isPublic(requiredType.getModifiers()) && ClassUtils.hasConstructor(requiredType));
680680
}

spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
6565

6666
private static final Log logger = LogFactory.getLog(DisposableBeanAdapter.class);
6767

68-
private static Class closeableInterface;
68+
private static Class<?> closeableInterface;
6969

7070
static {
7171
try {
@@ -86,14 +86,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
8686

8787
private final boolean nonPublicAccessAllowed;
8888

89+
private final AccessControlContext acc;
90+
8991
private String destroyMethodName;
9092

9193
private transient Method destroyMethod;
9294

9395
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
9496

95-
private final AccessControlContext acc;
96-
9797

9898
/**
9999
* Create a new DisposableBeanAdapter for the given bean.
@@ -150,9 +150,9 @@ private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDispos
150150
this.beanName = beanName;
151151
this.invokeDisposableBean = invokeDisposableBean;
152152
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
153+
this.acc = null;
153154
this.destroyMethodName = destroyMethodName;
154155
this.beanPostProcessors = postProcessors;
155-
this.acc = null;
156156
}
157157

158158

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright 2002-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.context.annotation.configuration;
18+
19+
import org.junit.Test;
20+
21+
import org.springframework.beans.factory.ObjectFactory;
22+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
23+
import org.springframework.context.annotation.Bean;
24+
import org.springframework.context.annotation.Configuration;
25+
import org.springframework.context.annotation.Scope;
26+
import org.springframework.context.annotation.ScopedProxyMode;
27+
28+
import static org.hamcrest.Matchers.*;
29+
import static org.junit.Assert.*;
30+
31+
/**
32+
* @author Phillip Webb
33+
*/
34+
public class Spr10744Tests {
35+
36+
private static int createCount = 0;
37+
38+
private static int scopeCount = 0;
39+
40+
41+
@Test
42+
public void testSpr10744() throws Exception {
43+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
44+
context.getBeanFactory().registerScope("myTestScope", new MyTestScope());
45+
context.register(MyTestConfiguration.class);
46+
context.refresh();
47+
48+
Foo bean1 = context.getBean("foo", Foo.class);
49+
Foo bean2 = context.getBean("foo", Foo.class);
50+
assertThat(bean1, sameInstance(bean2));
51+
52+
// Should have created a single instance for the proxy
53+
assertThat(createCount, equalTo(1));
54+
assertThat(scopeCount, equalTo(0));
55+
56+
// Proxy mode should create new scoped object on each method call
57+
bean1.getMessage();
58+
assertThat(createCount, equalTo(2));
59+
assertThat(scopeCount, equalTo(1));
60+
bean1.getMessage();
61+
assertThat(createCount, equalTo(3));
62+
assertThat(scopeCount, equalTo(2));
63+
64+
context.close();
65+
}
66+
67+
68+
private static class MyTestScope implements org.springframework.beans.factory.config.Scope {
69+
70+
@Override
71+
public Object get(String name, ObjectFactory<?> objectFactory) {
72+
scopeCount++;
73+
return objectFactory.getObject();
74+
}
75+
76+
@Override
77+
public Object remove(String name) {
78+
return null;
79+
}
80+
81+
@Override
82+
public void registerDestructionCallback(String name, Runnable callback) {
83+
}
84+
85+
@Override
86+
public Object resolveContextualObject(String key) {
87+
return null;
88+
}
89+
90+
@Override
91+
public String getConversationId() {
92+
return null;
93+
}
94+
}
95+
96+
97+
static class Foo {
98+
99+
public Foo() {
100+
createCount++;
101+
}
102+
103+
public String getMessage() {
104+
return "Hello";
105+
}
106+
}
107+
108+
109+
@Configuration
110+
static class MyConfiguration {
111+
112+
@Bean
113+
public Foo foo() {
114+
return new Foo();
115+
}
116+
}
117+
118+
119+
@Configuration
120+
static class MyTestConfiguration extends MyConfiguration {
121+
122+
@Bean
123+
@Scope(value = "myTestScope", proxyMode = ScopedProxyMode.TARGET_CLASS)
124+
@Override
125+
public Foo foo() {
126+
return new Foo();
127+
}
128+
}
129+
130+
}

spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-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.
@@ -25,6 +25,7 @@
2525

2626
import org.springframework.core.BridgeMethodResolver;
2727
import org.springframework.util.Assert;
28+
import org.springframework.util.ReflectionUtils;
2829

2930
/**
3031
* General utility methods for working with annotations, handling bridge methods (which the compiler
@@ -60,8 +61,8 @@ public abstract class AnnotationUtils {
6061
* Method, Constructor or Field. Meta-annotations will be searched if the annotation
6162
* is not declared locally on the supplied element.
6263
* @param ae the Method, Constructor or Field from which to get the annotation
63-
* @param annotationType the annotation class to look for, both locally and as a meta-annotation
64-
* @return the matching annotation or {@code null} if not found
64+
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
65+
* @return the matching annotation, or {@code null} if none found
6566
* @since 3.1
6667
*/
6768
public static <T extends Annotation> T getAnnotation(AnnotatedElement ae, Class<T> annotationType) {
@@ -92,7 +93,7 @@ public static Annotation[] getAnnotations(Method method) {
9293
* Get a single {@link Annotation} of {@code annotationType} from the supplied {@link Method}.
9394
* <p>Correctly handles bridge {@link Method Methods} generated by the compiler.
9495
* @param method the method to look for annotations on
95-
* @param annotationType the annotation class to look for
96+
* @param annotationType the annotation type to look for
9697
* @return the annotations found
9798
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
9899
*/
@@ -115,8 +116,8 @@ public static <A extends Annotation> A getAnnotation(Method method, Class<A> ann
115116
* traversing its super methods if no annotation can be found on the given method itself.
116117
* <p>Annotations on methods are not inherited by default, so we need to handle this explicitly.
117118
* @param method the method to look for annotations on
118-
* @param annotationType the annotation class to look for
119-
* @return the annotation found, or {@code null} if none found
119+
* @param annotationType the annotation type to look for
120+
* @return the annotation found, or {@code null} if none
120121
*/
121122
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
122123
A annotation = getAnnotation(method, annotationType);
@@ -192,7 +193,7 @@ private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
192193
* with the interfaces that the superclass declares. Recursing up through the entire superclass
193194
* hierarchy if no match is found.
194195
* @param clazz the class to look for annotations on
195-
* @param annotationType the annotation class to look for
196+
* @param annotationType the annotation type to look for
196197
* @return the annotation found, or {@code null} if none found
197198
*/
198199
public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
@@ -215,11 +216,11 @@ public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> a
215216
}
216217
}
217218
}
218-
Class<?> superClass = clazz.getSuperclass();
219-
if (superClass == null || superClass.equals(Object.class)) {
219+
Class<?> superclass = clazz.getSuperclass();
220+
if (superclass == null || superclass.equals(Object.class)) {
220221
return null;
221222
}
222-
return findAnnotation(superClass, annotationType);
223+
return findAnnotation(superclass, annotationType);
223224
}
224225

225226
/**
@@ -232,9 +233,8 @@ public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> a
232233
* <p>The standard {@link Class} API does not provide a mechanism for determining which class
233234
* in an inheritance hierarchy actually declares an {@link Annotation}, so we need to handle
234235
* this explicitly.
235-
* @param annotationType the Class object corresponding to the annotation type
236-
* @param clazz the Class object corresponding to the class on which to check for the annotation,
237-
* or {@code null}
236+
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
237+
* @param clazz the class on which to check for the annotation (may be {@code null})
238238
* @return the first {@link Class} in the inheritance hierarchy of the specified {@code clazz}
239239
* which declares an annotation for the specified {@code annotationType}, or {@code null}
240240
* if not found
@@ -248,8 +248,10 @@ public static Class<?> findAnnotationDeclaringClass(Class<? extends Annotation>
248248
if (clazz == null || clazz.equals(Object.class)) {
249249
return null;
250250
}
251-
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : findAnnotationDeclaringClass(
252-
annotationType, clazz.getSuperclass());
251+
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
252+
return clazz;
253+
}
254+
return findAnnotationDeclaringClass(annotationType, clazz.getSuperclass());
253255
}
254256

255257
/**
@@ -413,14 +415,13 @@ else if (value instanceof Class[]) {
413415
}
414416
if (nestedAnnotationsAsMap && value instanceof Annotation) {
415417
attrs.put(method.getName(),
416-
getAnnotationAttributes((Annotation) value, classValuesAsString, nestedAnnotationsAsMap));
418+
getAnnotationAttributes((Annotation) value, classValuesAsString, true));
417419
}
418420
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
419421
Annotation[] realAnnotations = (Annotation[]) value;
420422
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
421423
for (int i = 0; i < realAnnotations.length; i++) {
422-
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString,
423-
nestedAnnotationsAsMap);
424+
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString, true);
424425
}
425426
attrs.put(method.getName(), mappedAnnotations);
426427
}
@@ -456,7 +457,8 @@ public static Object getValue(Annotation annotation) {
456457
*/
457458
public static Object getValue(Annotation annotation, String attributeName) {
458459
try {
459-
Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]);
460+
Method method = annotation.annotationType().getDeclaredMethod(attributeName);
461+
ReflectionUtils.makeAccessible(method);
460462
return method.invoke(annotation);
461463
}
462464
catch (Exception ex) {
@@ -506,8 +508,7 @@ public static Object getDefaultValue(Class<? extends Annotation> annotationType)
506508
*/
507509
public static Object getDefaultValue(Class<? extends Annotation> annotationType, String attributeName) {
508510
try {
509-
Method method = annotationType.getDeclaredMethod(attributeName, new Class[0]);
510-
return method.getDefaultValue();
511+
return annotationType.getDeclaredMethod(attributeName).getDefaultValue();
511512
}
512513
catch (Exception ex) {
513514
return null;

spring-core/src/main/java/org/springframework/core/env/EnumerablePropertySource.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-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,6 +18,7 @@
1818

1919
import org.apache.commons.logging.Log;
2020
import org.apache.commons.logging.LogFactory;
21+
2122
import org.springframework.util.Assert;
2223

2324
/**
@@ -53,21 +54,22 @@ public EnumerablePropertySource(String name, T source) {
5354
super(name, source);
5455
}
5556

57+
5658
/**
57-
* Return the names of all properties contained by the {@linkplain #getSource()
58-
* source} object (never {@code null}).
59+
* Return the names of all properties contained by the
60+
* {@linkplain #getSource() source} object (never {@code null}).
5961
*/
6062
public abstract String[] getPropertyNames();
6163

6264
/**
6365
* Return whether this {@code PropertySource} contains a property with the given name.
64-
* <p>This implementation checks for the presence of the given name within
65-
* the {@link #getPropertyNames()} array.
66-
* @param name the property to find
66+
* <p>This implementation checks for the presence of the given name within the
67+
* {@link #getPropertyNames()} array.
68+
* @param name the name of the property to find
6769
*/
6870
public boolean containsProperty(String name) {
69-
Assert.notNull(name, "property name must not be null");
70-
for (String candidate : this.getPropertyNames()) {
71+
Assert.notNull(name, "Property name must not be null");
72+
for (String candidate : getPropertyNames()) {
7173
if (candidate.equals(name)) {
7274
if (logger.isDebugEnabled()) {
7375
logger.debug(String.format("PropertySource [%s] contains '%s'", getName(), name));

0 commit comments

Comments
 (0)