Fix possible duplicate templateEngine bean in Thymeleaf auto-config

Closes gh-30384
pull/30505/head
Andy Wilkinson 3 years ago
parent e927cd71dd
commit 8d882fa09b

@ -0,0 +1,79 @@
/*
* Copyright 2012-2022 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.thymeleaf;
import org.thymeleaf.ITemplateEngine;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.spring5.ISpringTemplateEngine;
import org.thymeleaf.spring5.ISpringWebFluxTemplateEngine;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.SpringWebFluxTemplateEngine;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration classes for Thymeleaf's {@link ITemplateEngine}. Imported by
* {@link ThymeleafAutoConfiguration}.
*
* @author Andy Wilkinson
*/
class TemplateEngineConfigurations {
@Configuration(proxyBeanMethods = false)
static class DefaultTemplateEngineConfiguration {
@Bean
@ConditionalOnMissingBean(ISpringTemplateEngine.class)
SpringTemplateEngine templateEngine(ThymeleafProperties properties,
ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
dialects.orderedStream().forEach(engine::addDialect);
return engine;
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.REACTIVE)
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
static class ReactiveTemplateEngineConfiguration {
@Bean
@ConditionalOnMissingBean(ISpringWebFluxTemplateEngine.class)
SpringWebFluxTemplateEngine templateEngine(ThymeleafProperties properties,
ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
SpringWebFluxTemplateEngine engine = new SpringWebFluxTemplateEngine();
engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
dialects.orderedStream().forEach(engine::addDialect);
return engine;
}
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 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.
@ -24,20 +24,15 @@ import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDiale
import nz.net.ultraq.thymeleaf.LayoutDialect; import nz.net.ultraq.thymeleaf.LayoutDialect;
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.thymeleaf.dialect.IDialect;
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect; import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect; import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
import org.thymeleaf.spring5.ISpringTemplateEngine;
import org.thymeleaf.spring5.ISpringWebFluxTemplateEngine; import org.thymeleaf.spring5.ISpringWebFluxTemplateEngine;
import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.SpringWebFluxTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver; import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.spring5.view.reactive.ThymeleafReactiveViewResolver; import org.thymeleaf.spring5.view.reactive.ThymeleafReactiveViewResolver;
import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -57,6 +52,7 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.security.web.server.csrf.CsrfToken; import org.springframework.security.web.server.csrf.CsrfToken;
import org.springframework.util.MimeType; import org.springframework.util.MimeType;
@ -80,6 +76,8 @@ import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
@EnableConfigurationProperties(ThymeleafProperties.class) @EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
@Import({ TemplateEngineConfigurations.ReactiveTemplateEngineConfiguration.class,
TemplateEngineConfigurations.DefaultTemplateEngineConfiguration.class })
public class ThymeleafAutoConfiguration { public class ThymeleafAutoConfiguration {
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ -130,23 +128,6 @@ public class ThymeleafAutoConfiguration {
} }
@Configuration(proxyBeanMethods = false)
protected static class ThymeleafDefaultConfiguration {
@Bean
@ConditionalOnMissingBean(ISpringTemplateEngine.class)
SpringTemplateEngine templateEngine(ThymeleafProperties properties,
ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
dialects.orderedStream().forEach(engine::addDialect);
return engine;
}
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true) @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
@ -199,25 +180,6 @@ public class ThymeleafAutoConfiguration {
} }
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.REACTIVE)
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
static class ThymeleafReactiveConfiguration {
@Bean
@ConditionalOnMissingBean(ISpringWebFluxTemplateEngine.class)
SpringWebFluxTemplateEngine templateEngine(ThymeleafProperties properties,
ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
SpringWebFluxTemplateEngine engine = new SpringWebFluxTemplateEngine();
engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
dialects.orderedStream().forEach(engine::addDialect);
return engine;
}
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.REACTIVE) @ConditionalOnWebApplication(type = Type.REACTIVE)
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true) @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)

Loading…
Cancel
Save