diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2019-01-01 11:22:29 +0100 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2019-01-01 11:22:29 +0100 |
commit | d2188a36ffbb40643baa12f9a68494774552563f (patch) | |
tree | be7118bd87b5b0960603ccda439d474261fbd69d /spring-context | |
parent | cb53abe54064010cd788530c7a882ecebb88afcd (diff) |
New upstream version 4.3.21
Diffstat (limited to 'spring-context')
7 files changed, 237 insertions, 30 deletions
diff --git a/spring-context/src/main/java/org/springframework/context/annotation/DependsOn.java b/spring-context/src/main/java/org/springframework/context/annotation/DependsOn.java index 121cec3a..48f3dc05 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/DependsOn.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/DependsOn.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -28,6 +28,12 @@ import java.lang.annotation.Target; * does not explicitly depend on another through properties or constructor arguments, * 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 * {@link org.springframework.stereotype.Component} or on methods annotated * with {@link Bean}. diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java index 42427f4c..473ba922 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java @@ -171,8 +171,23 @@ public class MethodValidationInterceptor implements MethodInterceptor { private boolean isFactoryBeanMetadataMethod(Method method) { Class<?> clazz = method.getDeclaringClass(); - return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) && - !method.getName().equals("getObject")); + + // Call from interface-based proxy handle, allowing for an efficient check? + if (clazz.isInterface()) { + return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) && + !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())); } /** diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index dcf2f373..dd053d7b 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -544,6 +544,10 @@ public class ConfigurationClassPostProcessorTests { beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); } @Test @@ -558,6 +562,78 @@ public class ConfigurationClassPostProcessorTests { beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + } + + @Test + public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawFactoryMethod() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + + String[] beanNames = beanFactory.getBeanNamesForType(Repository.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(0, beanNames.length); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(0, beanNames.length); + } + + @Test + public void genericsBasedInjectionWithLateGenericsMatchingAndRawFactoryMethod() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + beanFactory.preInstantiateSingletons(); + + String[] beanNames = beanFactory.getBeanNamesForType(Repository.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + } + + @Test + public void genericsBasedInjectionWithEarlyGenericsMatchingAndRawInstance() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + + String[] beanNames = beanFactory.getBeanNamesForType(Repository.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + } + + @Test + public void genericsBasedInjectionWithLateGenericsMatchingAndRawInstance() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + beanFactory.preInstantiateSingletons(); + + String[] beanNames = beanFactory.getBeanNamesForType(Repository.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); } @Test @@ -577,6 +653,10 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo"))); } @@ -598,12 +678,16 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo"))); } @Test public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawFactoryMethod() { - beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class)); + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class)); new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); autoProxyCreator.setProxyTargetClass(true); @@ -619,6 +703,35 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo"))); + } + + @Test + public void genericsBasedInjectionWithLateGenericsMatchingOnCglibProxyAndRawInstance() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); + autoProxyCreator.setProxyTargetClass(true); + autoProxyCreator.setBeanFactory(beanFactory); + beanFactory.addBeanPostProcessor(autoProxyCreator); + beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor())); + beanFactory.preInstantiateSingletons(); + + String[] beanNames = beanFactory.getBeanNamesForType(Repository.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isCglibProxy(beanFactory.getBean("stringRepo"))); } @@ -638,6 +751,10 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo"))); } @@ -658,12 +775,16 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo"))); } @Test public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawFactoryMethod() { - beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawRepositoryConfiguration.class)); + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawFactoryMethodRepositoryConfiguration.class)); new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); autoProxyCreator.setBeanFactory(beanFactory); @@ -678,6 +799,34 @@ public class ConfigurationClassPostProcessorTests { assertEquals(1, beanNames.length); assertEquals("stringRepo", beanNames[0]); + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo"))); + } + + @Test + public void genericsBasedInjectionWithLateGenericsMatchingOnJdkProxyAndRawInstance() { + beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawInstanceRepositoryConfiguration.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); + autoProxyCreator.setBeanFactory(beanFactory); + beanFactory.addBeanPostProcessor(autoProxyCreator); + beanFactory.registerSingleton("traceInterceptor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor())); + beanFactory.preInstantiateSingletons(); + + String[] beanNames = beanFactory.getBeanNamesForType(RepositoryInterface.class); + assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo")); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + + beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(RepositoryInterface.class, String.class)); + assertEquals(1, beanNames.length); + assertEquals("stringRepo", beanNames[0]); + assertTrue(AopUtils.isJdkDynamicProxy(beanFactory.getBean("stringRepo"))); } @@ -980,7 +1129,7 @@ public class ConfigurationClassPostProcessorTests { } @Configuration - public static class RawRepositoryConfiguration { + public static class RawFactoryMethodRepositoryConfiguration { @Bean public Repository stringRepo() { @@ -994,6 +1143,21 @@ public class ConfigurationClassPostProcessorTests { } @Configuration + public static class RawInstanceRepositoryConfiguration { + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Bean + public Repository<String> stringRepo() { + return new Repository() { + @Override + public String toString() { + return "Repository<String>"; + } + }; + } + } + + @Configuration public static class ScopedRepositoryConfiguration { @Bean diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index ed5b11fc..9eb5aefe 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -161,7 +161,7 @@ public class EnableAsyncTests { Object bean = ctx.getBean(CustomAsyncBean.class); assertTrue(AopUtils.isAopProxy(bean)); boolean isAsyncAdvised = false; - for (Advisor advisor : ((Advised)bean).getAdvisors()) { + for (Advisor advisor : ((Advised) bean).getAdvisors()) { if (advisor instanceof AsyncAnnotationAdvisor) { isAsyncAdvised = true; break; @@ -365,7 +365,8 @@ public class EnableAsyncTests { @EnableAsync static class AsyncConfigWithMockito { - @Bean @Lazy + @Bean + @Lazy public AsyncBean asyncBean() { return Mockito.mock(AsyncBean.class); } diff --git a/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java b/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java index 8cc22aab..00c3d24c 100644 --- a/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java +++ b/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -23,28 +23,29 @@ import javax.naming.NamingException; import org.springframework.jndi.JndiTemplate; /** - * Simple extension of the JndiTemplate class that always returns - * a given object. Very useful for testing. Effectively a mock object. + * Simple extension of the JndiTemplate class that always returns a given object. + * + * <p>Very useful for testing. Effectively a mock object. * * @author Rod Johnson * @author Juergen Hoeller */ 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 - * for given names. To be populated through {@code addObject} calls. + * Construct a new JndiTemplate that will always return given objects for + * given names. To be populated through {@code addObject} calls. * @see #addObject(String, Object) */ public ExpectedLookupTemplate() { } /** - * Construct a new JndiTemplate that will always return the - * given object, but honour only requests for the given name. + * Construct a new JndiTemplate that will always return the given object, + * but honour only requests for the given name. * @param name the name the client is expected to look up * @param object the object that will be returned */ @@ -54,8 +55,7 @@ public class ExpectedLookupTemplate extends JndiTemplate { /** - * Add the given object to the list of JNDI objects that this - * template will expose. + * Add the given object to the list of JNDI objects that this template will expose. * @param name the name the client is expected to look up * @param object the object that will be returned */ @@ -63,11 +63,10 @@ public class ExpectedLookupTemplate extends JndiTemplate { this.jndiObjects.put(name, object); } - /** - * If the name is the expected name specified in the constructor, - * return the object provided in the constructor. If the name is - * unexpected, a respective NamingException gets thrown. + * If the name is the expected name specified in the constructor, return the + * object provided in the constructor. If the name is unexpected, a + * respective NamingException gets thrown. */ @Override public Object lookup(String name) throws NamingException { diff --git a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java index 1ae3b78d..b4fe464e 100644 --- a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java +++ b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import javax.naming.spi.NamingManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** @@ -35,13 +36,14 @@ import org.springframework.util.ClassUtils; * configure JNDI appropriately, so that {@code new InitialContext()} * 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 - * 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: * <ul> * <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls) * <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> * * <p>Typical usage in bootstrap code: @@ -98,7 +100,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder /** * 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. * <p>This is mainly intended for test suites that want to * reinitialize JNDI bindings from scratch repeatedly. @@ -137,12 +139,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder logger.info("Activating simple JNDI environment"); synchronized (initializationLock) { if (!initialized) { - if (NamingManager.hasInitialContextFactoryBuilder()) { - throw new IllegalStateException( + Assert.state(!NamingManager.hasInitialContextFactoryBuilder(), "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, " + "with no reset option. As a consequence, a JNDI provider must only be registered once per JVM."); - } NamingManager.setInitialContextFactoryBuilder(this); initialized = true; } diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java index 63746bbb..dbd8b5cd 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java @@ -123,7 +123,16 @@ public class MethodValidationTests { @Test public void testLazyValidatorForMethodValidation() { 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)); } @@ -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; + } + } + } |