diff --git a/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java b/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java index 4f35f84ee0a..9b0c2b099fe 100644 --- a/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java +++ b/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ import java.io.Serializable; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.Test; +import test.mixin.LockMixinAdvisor; + import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodMatcher; import org.springframework.aop.Pointcut; @@ -34,7 +36,6 @@ import org.springframework.tests.aop.interceptor.NopInterceptor; import org.springframework.tests.sample.beans.ITestBean; import org.springframework.tests.sample.beans.TestBean; -import test.mixin.LockMixinAdvisor; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -140,9 +141,7 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri AopProxy aop = new CglibAopProxy(as); CglibTestBean proxy = (CglibTestBean) aop.getProxy(); - - assertEquals("The name property has been overwritten by the constructor", - "Rob Harrop", proxy.getName()); + assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.getName()); } @Test @@ -155,9 +154,7 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri pc.setTarget(target); CglibAopProxy aop = new CglibAopProxy(pc); - CglibTestBean proxy = (CglibTestBean) aop.getProxy(); - assertNotNull("Proxy should not be null", proxy); assertEquals("Constructor overrode the value of name", "Rob Harrop", proxy.getName()); @@ -187,21 +184,18 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri public ClassFilter getClassFilter() { return ClassFilter.TRUE; } - @Override public MethodMatcher getMethodMatcher() { return MethodMatcher.TRUE; } - - @Override - public int hashCode() { - return 0; - } - @Override public boolean equals(Object obj) { return true; } + @Override + public int hashCode() { + return 0; + } }; pf.addAdvisor(new DefaultPointcutAdvisor(pointcut, advice)); @@ -225,7 +219,7 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri } private ITestBean getIntroductionAdvisorProxy(TestBean target) { - ProxyFactory pf = new ProxyFactory(new Class[]{ITestBean.class}); + ProxyFactory pf = new ProxyFactory(new Class[] {ITestBean.class}); pf.setProxyTargetClass(true); pf.addAdvisor(new LockMixinAdvisor()); @@ -245,8 +239,7 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri AdvisedSupport pc = new AdvisedSupport(new Class[]{}); pc.setTargetSource(mockTargetSource); CglibAopProxy aop = new CglibAopProxy(pc); - aop.setConstructorArguments(new Object[] {"Rob Harrop", new Integer(22)}, - new Class[] {String.class, int.class}); + aop.setConstructorArguments(new Object[] {"Rob Harrop", 22}, new Class[] {String.class, int.class}); NoArgCtorTestBean proxy = (NoArgCtorTestBean) aop.getProxy(); proxy = (NoArgCtorTestBean) aop.getProxy(); diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index 57e5b3c9100..3a6d05752bb 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -77,19 +77,17 @@ import org.springframework.util.StringUtils; @SuppressWarnings("serial") public final class ResolvableType implements Serializable { - private static ConcurrentReferenceHashMap cache = - new ConcurrentReferenceHashMap(); - - /** * {@code ResolvableType} returned when no value is available. {@code NONE} is used * in preference to {@code null} so that multiple method calls can be safely chained. */ public static final ResolvableType NONE = new ResolvableType(null, null, null, null); - private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0]; + private static final ConcurrentReferenceHashMap cache = + new ConcurrentReferenceHashMap(256); + /** * The underlying Java type being managed (only ever {@code null} for {@link #NONE}). @@ -1085,7 +1083,7 @@ public final class ResolvableType implements Serializable { * @see #forType(Type, ResolvableType) */ public static ResolvableType forType(Type type) { - return forType(type, (VariableResolver) null); + return forType(type, null, null); } /** diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java index 4c8a1cf4e75..29514e9410c 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -132,6 +132,15 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen this(initialCapacity, DEFAULT_LOAD_FACTOR, concurrencyLevel, DEFAULT_REFERENCE_TYPE); } + /** + * Create a new {@code ConcurrentReferenceHashMap} instance. + * @param initialCapacity the initial capacity of the map + * @param referenceType the reference type used for entries (soft or weak) + */ + public ConcurrentReferenceHashMap(int initialCapacity, ReferenceType referenceType) { + this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL, referenceType); + } + /** * Create a new {@code ConcurrentReferenceHashMap} instance. * @param initialCapacity the initial capacity of the map @@ -151,7 +160,7 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen * table exceeds this value, resize will be attempted. * @param concurrencyLevel the expected number of threads that will concurrently * write to the map - * @param referenceType the reference type used for entries + * @param referenceType the reference type used for entries (soft or weak) */ @SuppressWarnings("unchecked") public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @@ -165,10 +174,10 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen this.shift = calculateShift(concurrencyLevel, MAXIMUM_CONCURRENCY_LEVEL); int size = 1 << this.shift; this.referenceType = referenceType; - int roundedUpSegmentCapactity = (int) ((initialCapacity + size - 1L) / size); + int roundedUpSegmentCapacity = (int) ((initialCapacity + size - 1L) / size); this.segments = (Segment[]) Array.newInstance(Segment.class, size); for (int i = 0; i < this.segments.length; i++) { - this.segments[i] = new Segment(roundedUpSegmentCapactity); + this.segments[i] = new Segment(roundedUpSegmentCapacity); } } @@ -186,8 +195,8 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen } /** - * Factory method that returns the {@link ReferenceManager}. This method will be - * called once for each {@link Segment}. + * Factory method that returns the {@link ReferenceManager}. + * This method will be called once for each {@link Segment}. * @return a new reference manager */ protected ReferenceManager createReferenceManager() { diff --git a/spring-core/src/main/java/org/springframework/util/CustomizableThreadCreator.java b/spring-core/src/main/java/org/springframework/util/CustomizableThreadCreator.java index 6a3e0dc0871..d8338d3bf34 100644 --- a/spring-core/src/main/java/org/springframework/util/CustomizableThreadCreator.java +++ b/spring-core/src/main/java/org/springframework/util/CustomizableThreadCreator.java @@ -20,8 +20,8 @@ import java.io.Serializable; import java.util.concurrent.atomic.AtomicInteger; /** - * Simple customizable helper class for creating threads. Provides various - * bean properties, such as thread name prefix, thread priority, etc. + * Simple customizable helper class for creating new {@link Thread} instances. + * Provides various bean properties: thread name prefix, thread priority, etc. * *

Serves as base class for thread factories such as * {@link org.springframework.scheduling.concurrent.CustomizableThreadFactory}. @@ -41,7 +41,7 @@ public class CustomizableThreadCreator implements Serializable { private ThreadGroup threadGroup; - private final AtomicInteger threadCount = new AtomicInteger(); + private final AtomicInteger threadCount = new AtomicInteger(0); /** @@ -95,11 +95,11 @@ public class CustomizableThreadCreator implements Serializable { /** * Set whether this factory is supposed to create daemon threads, * just executing as long as the application itself is running. - *

Default is "false": Concrete factories usually support explicit - * cancelling. Hence, if the application shuts down, Runnables will - * by default finish their execution. - *

Specify "true" for eager shutdown of threads which still - * actively execute a Runnable. + *

Default is "false": Concrete factories usually support explicit cancelling. + * Hence, if the application shuts down, Runnables will by default finish their + * execution. + *

Specify "true" for eager shutdown of threads which still actively execute + * a {@link Runnable} at the time that the application itself shuts down. * @see java.lang.Thread#setDaemon */ public void setDaemon(boolean daemon) { @@ -131,7 +131,7 @@ public class CustomizableThreadCreator implements Serializable { /** * Return the thread group that threads should be created in - * (or {@code null}) for the default group. + * (or {@code null} for the default group). */ public ThreadGroup getThreadGroup() { return this.threadGroup; @@ -139,9 +139,9 @@ public class CustomizableThreadCreator implements Serializable { /** - * Template method for the creation of a Thread. - *

Default implementation creates a new Thread for the given - * Runnable, applying an appropriate thread name. + * Template method for the creation of a new {@link Thread}. + *

The default implementation creates a new Thread for the given + * {@link Runnable}, applying an appropriate thread name. * @param runnable the Runnable to execute * @see #nextThreadName() */ @@ -153,10 +153,9 @@ public class CustomizableThreadCreator implements Serializable { } /** - * Return the thread name to use for a newly created thread. - *

Default implementation returns the specified thread name prefix - * with an increasing thread count appended: for example, - * "SimpleAsyncTaskExecutor-0". + * Return the thread name to use for a newly created {@link Thread}. + *

The default implementation returns the specified thread name prefix + * with an increasing thread count appended: e.g. "SimpleAsyncTaskExecutor-0". * @see #getThreadNamePrefix() */ protected String nextThreadName() { diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index 1b56bc73c4d..e544e6c751f 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,8 +44,13 @@ import java.util.regex.Pattern; */ public abstract class ReflectionUtils { + /** + * Pattern for detecting CGLIB-renamed methods. + * @see #isCglibRenamedMethod + */ private static final Pattern CGLIB_RENAMED_METHOD_PATTERN = Pattern.compile("CGLIB\\$(.+)\\$\\d+"); + /** * Attempt to find a {@link Field field} on the supplied {@link Class} with the * supplied {@code name}. Searches all superclasses up to {@link Object}. @@ -373,19 +378,21 @@ public abstract class ReflectionUtils { * Determine whether the given method is originally declared by {@link java.lang.Object}. */ public static boolean isObjectMethod(Method method) { + if (method == null) { + return false; + } try { Object.class.getDeclaredMethod(method.getName(), method.getParameterTypes()); return true; - } catch (SecurityException ex) { - return false; - } catch (NoSuchMethodException ex) { + } + catch (Exception ex) { return false; } } /** - * Determine whether the given method is a CGLIB 'renamed' method, following - * the pattern "CGLIB$methodName$0". + * Determine whether the given method is a CGLIB 'renamed' method, + * following the pattern "CGLIB$methodName$0". * @param renamedMethod the method to check * @see org.springframework.cglib.proxy.Enhancer#rename */ @@ -514,15 +521,15 @@ public abstract class ReflectionUtils { public void doWith(Method method) { boolean knownSignature = false; Method methodBeingOverriddenWithCovariantReturnType = null; - for (Method existingMethod : methods) { if (method.getName().equals(existingMethod.getName()) && Arrays.equals(method.getParameterTypes(), existingMethod.getParameterTypes())) { - // is this a covariant return type situation? + // Is this a covariant return type situation? if (existingMethod.getReturnType() != method.getReturnType() && existingMethod.getReturnType().isAssignableFrom(method.getReturnType())) { methodBeingOverriddenWithCovariantReturnType = existingMethod; - } else { + } + else { knownSignature = true; } break; diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java index 6118c82af97..47412fc18ad 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,11 @@ package org.springframework.expression.spel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - import java.util.HashMap; import java.util.Map; import org.junit.Test; + import org.springframework.expression.AccessException; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; @@ -32,6 +30,8 @@ import org.springframework.expression.TypedValue; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; +import static org.junit.Assert.*; + /** * Testing variations on map access. * @@ -73,64 +73,60 @@ public class MapAccessTests extends ExpressionTestCase { @Test public void testGetValue(){ - - Map props1= new HashMap(); + Map props1 = new HashMap(); props1.put("key1", "value1"); props1.put("key2", "value2"); props1.put("key3", "value3"); - - Object bean = new TestBean("name1",new TestBean("name2",null,"Description 2",15,props1),"description 1", 6,props1); + Object bean = new TestBean("name1", new TestBean("name2", null, "Description 2", 15, props1), "description 1", 6, props1); ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("testBean.properties['key2']"); String key = (String) exp.getValue(bean); assertNotNull(key); - } - public static class TestBean - { + + public static class TestBean { + private String name; private TestBean testBean; private String description; private Integer priority; - private Map properties; + private Map properties; - - public TestBean() { - super(); - } - - public TestBean(String name, TestBean testBean, String description,Integer priority,Map props) { - super(); + public TestBean(String name, TestBean testBean, String description, Integer priority, Map props) { this.name = name; this.testBean = testBean; this.description = description; - this.priority=priority; - this.properties=props; + this.priority = priority; + this.properties = props; } public String getName() { return name; } + public void setName(String name) { this.name = name; } + public TestBean getTestBean() { return testBean; } + public void setTestBean(TestBean testBean) { this.testBean = testBean; } + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } - public Integer getPriority() { return priority; } @@ -168,16 +164,14 @@ public class MapAccessTests extends ExpressionTestCase { @Override @SuppressWarnings("unchecked") - public void write(EvaluationContext context, Object target, String name, Object newValue) - throws AccessException { + public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { ((Map) target).put(name, newValue); } @Override public Class[] getSpecificTargetClasses() { - return new Class[] { Map.class }; + return new Class[] {Map.class}; } - } }