Commit b3c3c7a6 authored by Emmanuel Bourg's avatar Emmanuel Bourg

Update upstream source from tag 'upstream/4.3.21'

Update to upstream version '4.3.21'
with Debian dir f09f025ebbc9ed9e77437b0a4c7fd1385a79ead5
parents 8b3e0271 d2188a36
...@@ -41,7 +41,7 @@ configure(allprojects) { project -> ...@@ -41,7 +41,7 @@ configure(allprojects) { project ->
ext.fileuploadVersion = "1.3.3" ext.fileuploadVersion = "1.3.3"
ext.freemarkerVersion = "2.3.23" ext.freemarkerVersion = "2.3.23"
ext.groovyVersion = "2.4.15" ext.groovyVersion = "2.4.15"
ext.gsonVersion = "2.8.2" ext.gsonVersion = "2.8.5"
ext.guavaVersion = "20.0" ext.guavaVersion = "20.0"
ext.hamcrestVersion = "1.3" ext.hamcrestVersion = "1.3"
ext.hibernate3Version = "3.6.10.Final" ext.hibernate3Version = "3.6.10.Final"
...@@ -50,9 +50,9 @@ configure(allprojects) { project -> ...@@ -50,9 +50,9 @@ configure(allprojects) { project ->
ext.hibval4Version = "4.3.2.Final" ext.hibval4Version = "4.3.2.Final"
ext.hibval5Version = "5.2.5.Final" ext.hibval5Version = "5.2.5.Final"
ext.hsqldbVersion = "2.3.4" ext.hsqldbVersion = "2.3.4"
ext.httpasyncVersion = "4.1.3" ext.httpasyncVersion = "4.1.4"
ext.httpclientVersion = "4.5.5" ext.httpclientVersion = "4.5.6"
ext.jackson2Version = "2.8.11.2" ext.jackson2Version = "2.8.11.3"
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
ext.javamailVersion = "1.5.6" ext.javamailVersion = "1.5.6"
ext.jettyVersion = "9.3.14.v20161028" // as of 9.3.15, Jetty has hard Servlet 3.1 requirement ext.jettyVersion = "9.3.14.v20161028" // as of 9.3.15, Jetty has hard Servlet 3.1 requirement
...@@ -62,7 +62,7 @@ configure(allprojects) { project -> ...@@ -62,7 +62,7 @@ configure(allprojects) { project ->
ext.jtaVersion = "1.2" ext.jtaVersion = "1.2"
ext.junitVersion = "4.12" ext.junitVersion = "4.12"
ext.log4jVersion = "1.2.17" ext.log4jVersion = "1.2.17"
ext.nettyVersion = "4.1.29.Final" ext.nettyVersion = "4.1.31.Final"
ext.okhttpVersion = "2.7.5" ext.okhttpVersion = "2.7.5"
ext.okhttp3Version = "3.8.1" ext.okhttp3Version = "3.8.1"
ext.openjpaVersion = "2.4.2" ext.openjpaVersion = "2.4.2"
...@@ -71,11 +71,11 @@ configure(allprojects) { project -> ...@@ -71,11 +71,11 @@ configure(allprojects) { project ->
ext.romeVersion = "1.7.4" ext.romeVersion = "1.7.4"
ext.slf4jVersion = "1.7.25" ext.slf4jVersion = "1.7.25"
ext.snakeyamlVersion = "1.17" ext.snakeyamlVersion = "1.17"
ext.snifferVersion = "1.16" ext.snifferVersion = "1.17"
ext.testngVersion = "6.9.10" ext.testngVersion = "6.9.10"
ext.tiles2Version = "2.2.2" ext.tiles2Version = "2.2.2"
ext.tiles3Version = "3.0.7" ext.tiles3Version = "3.0.8"
ext.tomcatVersion = "8.5.33" ext.tomcatVersion = "8.5.35"
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
ext.undertowVersion = "1.3.33.Final" ext.undertowVersion = "1.3.33.Final"
ext.xmlunitVersion = "1.6" ext.xmlunitVersion = "1.6"
...@@ -289,10 +289,9 @@ project("spring-build-src") { ...@@ -289,10 +289,9 @@ project("spring-build-src") {
project("spring-core") { project("spring-core") {
description = "Spring Core" description = "Spring Core"
// As of Spring 4.0.3, spring-core includes asm 5.x and repackages cglib 3.2, inlining // spring-core includes asm and repackages cglib, inlining both into the spring-core jar.
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.x and is therefore // cglib itself depends on asm and is therefore further transformed by the JarJar task to
// further transformed by the JarJar task to depend on org.springframework.asm; this // depend on org.springframework.asm; this avoids including two different copies of asm.
// avoids including two different copies of asm unnecessarily.
def cglibVersion = "3.2.6" def cglibVersion = "3.2.6"
def objenesisVersion = "2.6" def objenesisVersion = "2.6"
......
version=4.3.20.RELEASE version=4.3.21.RELEASE
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -43,8 +43,10 @@ import org.springframework.util.ObjectUtils; ...@@ -43,8 +43,10 @@ import org.springframework.util.ObjectUtils;
* Decorator for a standard {@link BeanInfo} object, e.g. as created by * Decorator for a standard {@link BeanInfo} object, e.g. as created by
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register static * {@link Introspector#getBeanInfo(Class)}, designed to discover and register static
* and/or non-void returning setter methods. For example: * and/or non-void returning setter methods. For example:
*
* <pre class="code"> * <pre class="code">
* public class Bean { * public class Bean {
*
* private Foo foo; * private Foo foo;
* *
* public Foo getFoo() { * public Foo getFoo() {
...@@ -56,6 +58,7 @@ import org.springframework.util.ObjectUtils; ...@@ -56,6 +58,7 @@ import org.springframework.util.ObjectUtils;
* return this; * return this;
* } * }
* }</pre> * }</pre>
*
* The standard JavaBeans {@code Introspector} will discover the {@code getFoo} read * The standard JavaBeans {@code Introspector} will discover the {@code getFoo} read
* method, but will bypass the {@code #setFoo(Foo)} write method, because its non-void * method, but will bypass the {@code #setFoo(Foo)} write method, because its non-void
* returning signature does not comply with the JavaBeans specification. * returning signature does not comply with the JavaBeans specification.
...@@ -68,6 +71,7 @@ import org.springframework.util.ObjectUtils; ...@@ -68,6 +71,7 @@ import org.springframework.util.ObjectUtils;
* indexed properties</a> are fully supported. * indexed properties</a> are fully supported.
* *
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller
* @since 3.1 * @since 3.1
* @see #ExtendedBeanInfo(BeanInfo) * @see #ExtendedBeanInfo(BeanInfo)
* @see ExtendedBeanInfoFactory * @see ExtendedBeanInfoFactory
......
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -243,7 +243,9 @@ public interface ListableBeanFactory extends BeanFactory { ...@@ -243,7 +243,9 @@ public interface ListableBeanFactory extends BeanFactory {
/** /**
* Find all names of beans whose {@code Class} has the supplied {@link Annotation} * Find all names of beans whose {@code Class} has the supplied {@link Annotation}
* type, without creating any bean instances yet. * type, without creating corresponding bean instances yet.
* <p>Note that this method considers objects created by FactoryBeans, which means
* that FactoryBeans will get initialized in order to determine their object type.
* @param annotationType the type of annotation to look for * @param annotationType the type of annotation to look for
* @return the names of all matching beans * @return the names of all matching beans
* @since 4.0 * @since 4.0
...@@ -253,6 +255,8 @@ public interface ListableBeanFactory extends BeanFactory { ...@@ -253,6 +255,8 @@ public interface ListableBeanFactory extends BeanFactory {
/** /**
* Find all beans whose {@code Class} has the supplied {@link Annotation} type, * Find all beans whose {@code Class} has the supplied {@link Annotation} type,
* returning a Map of bean names with corresponding bean instances. * returning a Map of bean names with corresponding bean instances.
* <p>Note that this method considers objects created by FactoryBeans, which means
* that FactoryBeans will get initialized in order to determine their object type.
* @param annotationType the type of annotation to look for * @param annotationType the type of annotation to look for
* @return a Map with the matching beans, containing the bean names as * @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values * keys and the corresponding bean instances as values
...@@ -267,7 +271,7 @@ public interface ListableBeanFactory extends BeanFactory { ...@@ -267,7 +271,7 @@ public interface ListableBeanFactory extends BeanFactory {
* found on the given class itself. * found on the given class itself.
* @param beanName the name of the bean to look for annotations on * @param beanName the name of the bean to look for annotations on
* @param annotationType the annotation class to look for * @param annotationType the annotation class to look for
* @return the annotation of the given type if found, or {@code null} * @return the annotation of the given type if found, or {@code null} otherwise
* @throws NoSuchBeanDefinitionException if there is no bean with the given name * @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 3.0 * @since 3.0
*/ */
......
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -44,26 +44,25 @@ public class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver ...@@ -44,26 +44,25 @@ public class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver
} }
/** /**
* Build the BeanWiringInfo for the given Configurable annotation. * Build the {@link BeanWiringInfo} for the given {@link Configurable} annotation.
* @param beanInstance the bean instance * @param beanInstance the bean instance
* @param annotation the Configurable annotation found on the bean class * @param annotation the Configurable annotation found on the bean class
* @return the resolved BeanWiringInfo * @return the resolved BeanWiringInfo
*/ */
protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) { protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) {
if (!Autowire.NO.equals(annotation.autowire())) { if (!Autowire.NO.equals(annotation.autowire())) {
// Autowiring by name or by type
return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck()); return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck());
} }
else { else if (!"".equals(annotation.value())) {
if (!"".equals(annotation.value())) { // Explicitly specified bean name for bean definition to take property values from
// explicitly specified bean name
return new BeanWiringInfo(annotation.value(), false); return new BeanWiringInfo(annotation.value(), false);
} }
else { else {
// default bean name // Default bean name for bean definition to take property values from
return new BeanWiringInfo(getDefaultBeanName(beanInstance), true); return new BeanWiringInfo(getDefaultBeanName(beanInstance), true);
} }
} }
}
/** /**
* Determine the default bean name for the specified bean instance. * Determine the default bean name for the specified bean instance.
......
...@@ -509,12 +509,21 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp ...@@ -509,12 +509,21 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Generics potentially only match on the target class, not on the proxy... // Generics potentially only match on the target class, not on the proxy...
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
Class<?> targetType = mbd.getTargetType(); Class<?> targetType = mbd.getTargetType();
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance) && if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
typeToMatch.isAssignableFrom(targetType)) {
// Check raw class match as well, making sure it's exposed on the proxy. // Check raw class match as well, making sure it's exposed on the proxy.
Class<?> classToMatch = typeToMatch.resolve(); Class<?> classToMatch = typeToMatch.resolve();
return (classToMatch == null || classToMatch.isInstance(beanInstance)); if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
return false;
} }
if (typeToMatch.isAssignableFrom(targetType)) {
return true;
}
}
ResolvableType resolvableType = mbd.targetType;
if (resolvableType == null) {
resolvableType = mbd.factoryMethodReturnType;
}
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
} }
} }
return false; return false;
...@@ -1363,6 +1372,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp ...@@ -1363,6 +1372,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
*/ */
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch) protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException { throws CannotLoadBeanClassException {
try { try {
if (mbd.hasBeanClass()) { if (mbd.hasBeanClass()) {
return mbd.getBeanClass(); return mbd.getBeanClass();
......
...@@ -1574,7 +1574,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto ...@@ -1574,7 +1574,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
} }
} }
// Lenient fallback: dummy factory in case of original factory not found... // Lenient fallback: dummy factory in case of original factory not found...
return new DefaultListableBeanFactory(); DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory();
dummyFactory.serializationId = this.id;
return dummyFactory;
} }
} }
......
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -28,6 +28,12 @@ import java.lang.annotation.Target; ...@@ -28,6 +28,12 @@ import java.lang.annotation.Target;
* does not explicitly depend on another through properties or constructor arguments, * does not explicitly depend on another through properties or constructor arguments,
* but rather depends on the side effects of another bean's initialization. * but rather depends on the side effects of another bean's initialization.
* *
* <p>A depends-on declaration can specify both an initialization-time dependency and,
* in the case of singleton beans only, a corresponding destruction-time dependency.
* Dependent beans that define a depends-on relationship with a given bean are destroyed
* first, prior to the given bean itself being destroyed. Thus, a depends-on declaration
* can also control shutdown order.
*
* <p>May be used on any class directly or indirectly annotated with * <p>May be used on any class directly or indirectly annotated with
* {@link org.springframework.stereotype.Component} or on methods annotated * {@link org.springframework.stereotype.Component} or on methods annotated
* with {@link Bean}. * with {@link Bean}.
......
...@@ -171,10 +171,25 @@ public class MethodValidationInterceptor implements MethodInterceptor { ...@@ -171,10 +171,25 @@ public class MethodValidationInterceptor implements MethodInterceptor {
private boolean isFactoryBeanMetadataMethod(Method method) { private boolean isFactoryBeanMetadataMethod(Method method) {
Class<?> clazz = method.getDeclaringClass(); Class<?> clazz = method.getDeclaringClass();
// Call from interface-based proxy handle, allowing for an efficient check?
if (clazz.isInterface()) {
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) && return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
!method.getName().equals("getObject")); !method.getName().equals("getObject"));
} }
// Call from CGLIB proxy handle, potentially implementing a FactoryBean method?
Class<?> factoryBeanType = null;
if (SmartFactoryBean.class.isAssignableFrom(clazz)) {
factoryBeanType = SmartFactoryBean.class;
}
else if (FactoryBean.class.isAssignableFrom(clazz)) {
factoryBeanType = FactoryBean.class;
}
return (factoryBeanType != null && !method.getName().equals("getObject") &&
ClassUtils.hasMethod(factoryBeanType, method.getName(), method.getParameterTypes()));
}
/** /**
* Determine the validation groups to validate against for the given method invocation. * Determine the validation groups to validate against for the given method invocation.
* <p>Default are the validation groups as specified in the {@link Validated} annotation * <p>Default are the validation groups as specified in the {@link Validated} annotation
......
...@@ -161,7 +161,7 @@ public class EnableAsyncTests { ...@@ -161,7 +161,7 @@ public class EnableAsyncTests {
Object bean = ctx.getBean(CustomAsyncBean.class); Object bean = ctx.getBean(CustomAsyncBean.class);
assertTrue(AopUtils.isAopProxy(bean)); assertTrue(AopUtils.isAopProxy(bean));
boolean isAsyncAdvised = false; boolean isAsyncAdvised = false;
for (Advisor advisor : ((Advised)bean).getAdvisors()) { for (Advisor advisor : ((Advised) bean).getAdvisors()) {
if (advisor instanceof AsyncAnnotationAdvisor) { if (advisor instanceof AsyncAnnotationAdvisor) {
isAsyncAdvised = true; isAsyncAdvised = true;
break; break;
...@@ -365,7 +365,8 @@ public class EnableAsyncTests { ...@@ -365,7 +365,8 @@ public class EnableAsyncTests {
@EnableAsync @EnableAsync
static class AsyncConfigWithMockito { static class AsyncConfigWithMockito {
@Bean @Lazy @Bean
@Lazy
public AsyncBean asyncBean() { public AsyncBean asyncBean() {
return Mockito.mock(AsyncBean.class); return Mockito.mock(AsyncBean.class);
} }
......
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -23,28 +23,29 @@ import javax.naming.NamingException; ...@@ -23,28 +23,29 @@ import javax.naming.NamingException;
import org.springframework.jndi.JndiTemplate; import org.springframework.jndi.JndiTemplate;
/** /**
* Simple extension of the JndiTemplate class that always returns * Simple extension of the JndiTemplate class that always returns a given object.
* a given object. Very useful for testing. Effectively a mock object. *
* <p>Very useful for testing. Effectively a mock object.
* *
* @author Rod Johnson * @author Rod Johnson
* @author Juergen Hoeller * @author Juergen Hoeller
*/ */
public class ExpectedLookupTemplate extends JndiTemplate { public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>(); private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>(16);
/** /**
* Construct a new JndiTemplate that will always return given objects * Construct a new JndiTemplate that will always return given objects for
* for given names. To be populated through {@code addObject} calls. * given names. To be populated through {@code addObject} calls.
* @see #addObject(String, Object) * @see #addObject(String, Object)
*/ */
public ExpectedLookupTemplate() { public ExpectedLookupTemplate() {
} }
/** /**
* Construct a new JndiTemplate that will always return the * Construct a new JndiTemplate that will always return the given object,
* given object, but honour only requests for the given name. * but honour only requests for the given name.
* @param name the name the client is expected to look up * @param name the name the client is expected to look up
* @param object the object that will be returned * @param object the object that will be returned
*/ */
...@@ -54,8 +55,7 @@ public class ExpectedLookupTemplate extends JndiTemplate { ...@@ -54,8 +55,7 @@ public class ExpectedLookupTemplate extends JndiTemplate {
/** /**
* Add the given object to the list of JNDI objects that this * Add the given object to the list of JNDI objects that this template will expose.
* template will expose.
* @param name the name the client is expected to look up * @param name the name the client is expected to look up
* @param object the object that will be returned * @param object the object that will be returned
*/ */
...@@ -63,11 +63,10 @@ public class ExpectedLookupTemplate extends JndiTemplate { ...@@ -63,11 +63,10 @@ public class ExpectedLookupTemplate extends JndiTemplate {
this.jndiObjects.put(name, object); this.jndiObjects.put(name, object);
} }
/** /**
* If the name is the expected name specified in the constructor, * If the name is the expected name specified in the constructor, return the
* return the object provided in the constructor. If the name is * object provided in the constructor. If the name is unexpected, a
* unexpected, a respective NamingException gets thrown. * respective NamingException gets thrown.
*/ */
@Override @Override
public Object lookup(String name) throws NamingException { public Object lookup(String name) throws NamingException {
......
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -26,6 +26,7 @@ import javax.naming.spi.NamingManager; ...@@ -26,6 +26,7 @@ import javax.naming.spi.NamingManager;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
...@@ -35,13 +36,14 @@ import org.springframework.util.ClassUtils; ...@@ -35,13 +36,14 @@ import org.springframework.util.ClassUtils;
* configure JNDI appropriately, so that {@code new InitialContext()} * configure JNDI appropriately, so that {@code new InitialContext()}
* will expose the required objects. Also usable for standalone applications, * will expose the required objects. Also usable for standalone applications,
* e.g. for binding a JDBC DataSource to a well-known JNDI location, to be * e.g. for binding a JDBC DataSource to a well-known JNDI location, to be
* able to use traditional J2EE data access code outside of a J2EE container. * able to use traditional Java EE data access code outside of a Java EE
* container.
* *
* <p>There are various choices for DataSource implementations: * <p>There are various choices for DataSource implementations:
* <ul> * <ul>
* <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls) * <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls)
* <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call) * <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call)
* <li>Apache's Jakarta Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool) * <li>Apache's Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
* </ul> * </ul>
* *
* <p>Typical usage in bootstrap code: * <p>Typical usage in bootstrap code:
...@@ -98,7 +100,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder ...@@ -98,7 +100,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
/** /**
* If no SimpleNamingContextBuilder is already configuring JNDI, * If no SimpleNamingContextBuilder is already configuring JNDI,
* create and activate one. Otherwise take the existing activate * create and activate one. Otherwise take the existing activated
* SimpleNamingContextBuilder, clear it and return it. * SimpleNamingContextBuilder, clear it and return it.
* <p>This is mainly intended for test suites that want to * <p>This is mainly intended for test suites that want to
* reinitialize JNDI bindings from scratch repeatedly. * reinitialize JNDI bindings from scratch repeatedly.
...@@ -137,12 +139,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder ...@@ -137,12 +139,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
logger.info("Activating simple JNDI environment"); logger.info("Activating simple JNDI environment");
synchronized (initializationLock) { synchronized (initializationLock) {
if (!initialized) { if (!initialized) {
if (NamingManager.hasInitialContextFactoryBuilder()) { Assert.state(!NamingManager.hasInitialContextFactoryBuilder(),
throw new IllegalStateException(
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " + "Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " + "Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM."); "with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
}
NamingManager.setInitialContextFactoryBuilder(this); NamingManager.setInitialContextFactoryBuilder(this);
initialized = true; initialized = true;
} }
......
...@@ -123,7 +123,16 @@ public class MethodValidationTests { ...@@ -123,7 +123,16 @@ public class MethodValidationTests {
@Test @Test
public void testLazyValidatorForMethodValidation() { public void testLazyValidatorForMethodValidation() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class); LazyMethodValidationConfig.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
}
@Test
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5)); ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
} }
...@@ -223,4 +232,17 @@ public class MethodValidationTests { ...@@ -223,4 +232,17 @@ public class MethodValidationTests {
} }
} }
@Configuration
public static class LazyMethodValidationConfigWithProxyTargetClass {
@Bean
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator);
postProcessor.setProxyTargetClass(true);
return postProcessor;
}
}
} }
/** /**
* Spring's repackaging of * Spring's repackaging of
* <a href="http://asm.ow2.org">ASM</a> * <a href="http://asm.ow2.org">ASM 6.0</a>
* (for internal use only). * (with Spring-specific patches; for internal use only).
* *
* <p>This repackaging technique avoids any potential conflicts with * <p>This repackaging technique avoids any potential conflicts with
* dependencies on ASM at the application level or from third-party * dependencies on ASM at the application level or from third-party
......
/** /**
* Spring's repackaging of * Spring's repackaging of
* <a href="http://cglib.sourceforge.net">CGLIB</a> * <a href="https://github.com/cglib/cglib">CGLIB 3.2</a>
* (for internal use only). * (with Spring naming strategy; for internal use only).
* *
* <p>This repackaging technique avoids any potential conflicts with * <p>This repackaging technique avoids any potential conflicts with
* dependencies on CGLIB at the application level or from third-party * dependencies on CGLIB at the application level or from third-party
......
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. <