diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index e2b822816d..43d747f90c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -237,7 +237,7 @@ class CglibAopProxy implements AopProxy, Serializable { * validates it if not. */ private void validateClassIfNecessary(Class proxySuperClass, @Nullable ClassLoader proxyClassLoader) { - if (logger.isWarnEnabled()) { + if (!this.advised.isOptimize() && logger.isInfoEnabled()) { synchronized (validatedClasses) { if (!validatedClasses.containsKey(proxySuperClass)) { doValidateClass(proxySuperClass, proxyClassLoader, diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java index 38665cafbc..3b6010f8f5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 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. @@ -73,11 +73,9 @@ public class ProxyConfig implements Serializable { * The exact meaning of "aggressive optimizations" will differ * between proxies, but there is usually some tradeoff. * Default is "false". - *

For example, optimization will usually mean that advice changes won't - * take effect after a proxy has been created. For this reason, optimization - * is disabled by default. An optimize value of "true" may be ignored - * if other settings preclude optimization: for example, if "exposeProxy" - * is set to "true" and that's not compatible with the optimization. + *

With Spring's current proxy options, this flag effectively + * enforces CGLIB proxies (similar to {@link #setProxyTargetClass}) + * but without any class validation checks (for final methods etc). */ public void setOptimize(boolean optimize) { this.optimize = optimize; diff --git a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java index c2a0235d19..b58795014b 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java +++ b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -24,6 +24,7 @@ import org.springframework.beans.factory.BeanExpressionException; import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; @@ -156,10 +157,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver { sec.addPropertyAccessor(new EnvironmentAccessor()); sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory())); sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader())); - ConversionService conversionService = evalContext.getBeanFactory().getConversionService(); - if (conversionService != null) { - sec.setTypeConverter(new StandardTypeConverter(conversionService)); - } + sec.setTypeConverter(new StandardTypeConverter(() -> { + ConversionService cs = evalContext.getBeanFactory().getConversionService(); + return (cs != null ? cs : DefaultConversionService.getSharedInstance()); + })); customizeEvaluationContext(sec); this.evaluationCache.put(evalContext, sec); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java index a63a94be18..0f6c5b0640 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostConstructAndAutowiringTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -24,7 +24,6 @@ import org.springframework.beans.testfixture.beans.TestBean; import static org.assertj.core.api.Assertions.assertThat; - /** * Tests cornering the issue reported in SPR-8080. If the product of a @Bean method * was @Autowired into a configuration class while at the same time the declaring @@ -33,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; * 'currently in creation' status of the autowired bean and result in creating multiple * instances of the given @Bean, violating container scoping / singleton semantics. * - * This is resolved through no longer relying on 'currently in creation' status, but + *

This is resolved through no longer relying on 'currently in creation' status, but * rather on a thread local that informs the enhanced bean method implementation whether * the factory is the caller or not. * diff --git a/spring-core/src/main/java/org/springframework/asm/ClassReader.java b/spring-core/src/main/java/org/springframework/asm/ClassReader.java index d53564c2a9..e5c2113993 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -324,7 +324,9 @@ public class ClassReader { } outputStream.flush(); if (readCount == 1) { - return data; + // SPRING PATCH: some misbehaving InputStreams return -1 but still write to buffer (gh-27429) + // return data; + // END OF PATCH } return outputStream.toByteArray(); } finally { diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 37fc922b5b..1b62cc5655 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -275,6 +275,7 @@ public class ReactiveAdapterRegistry { } } + private static class RxJava3Registrar { void registerAdapters(ReactiveAdapterRegistry registry) { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index 8d1a250288..eeb1c09397 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 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,6 +16,8 @@ package org.springframework.expression.spel.support; +import java.util.function.Supplier; + import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; @@ -37,7 +39,7 @@ import org.springframework.util.Assert; */ public class StandardTypeConverter implements TypeConverter { - private final ConversionService conversionService; + private final Supplier conversionService; /** @@ -45,7 +47,7 @@ public class StandardTypeConverter implements TypeConverter { * @see DefaultConversionService#getSharedInstance() */ public StandardTypeConverter() { - this.conversionService = DefaultConversionService.getSharedInstance(); + this.conversionService = DefaultConversionService::getSharedInstance; } /** @@ -54,20 +56,30 @@ public class StandardTypeConverter implements TypeConverter { */ public StandardTypeConverter(ConversionService conversionService) { Assert.notNull(conversionService, "ConversionService must not be null"); + this.conversionService = () -> conversionService; + } + + /** + * Create a StandardTypeConverter for the given ConversionService. + * @param conversionService a Supplier for the ConversionService to delegate to + * @since 5.3.11 + */ + public StandardTypeConverter(Supplier conversionService) { + Assert.notNull(conversionService, "Supplier must not be null"); this.conversionService = conversionService; } @Override public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { - return this.conversionService.canConvert(sourceType, targetType); + return this.conversionService.get().canConvert(sourceType, targetType); } @Override @Nullable public Object convertValue(@Nullable Object value, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { try { - return this.conversionService.convert(value, sourceType, targetType); + return this.conversionService.get().convert(value, sourceType, targetType); } catch (ConversionException ex) { throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,