Ignore scoped targets when collecting servlet context initializer beans

Previously, there were two problems with servlet context initializer
beans that are a scoped proxy:

1. When there's no explicit registration bean the target of the scoped
   proxy is registered rather than the proxy. This meant that the
   proxy had no effect as it was being bypassed.
2. When there is an explicit registration bean, the registration is
   performed twice: the faulty implicit registration described above
   and explicit registration.

A fix (SPR-14816) has been made in Spring Framework so that we can
correctly determine the type of bean that will be produced by a
scoped proxy's factory bean. That change, coupled with the change in
this commit that ignored beans that are the target of a scoped proxy
addresses both of the problems described above. A single registration
is now performed and its the scoped proxy, rather than its target,
that is registered.

Closes gh-7150
pull/7269/head
Andy Wilkinson 8 years ago
parent 7e8c5f5940
commit 4919c6f30c

@ -36,6 +36,7 @@ import javax.servlet.Servlet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
@ -229,7 +230,7 @@ public class ServletContextInitializerBeans
String[] names = beanFactory.getBeanNamesForType(type, true, false);
Map<String, T> map = new LinkedHashMap<String, T>();
for (String name : names) {
if (!excludes.contains(name)) {
if (!excludes.contains(name) && !ScopedProxyUtils.isScopedTarget(name)) {
T bean = beanFactory.getBean(name, type);
if (!excludes.contains(bean)) {
map.put(name, bean);

@ -0,0 +1,95 @@
/*
* Copyright 2012-2016 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
*
* http://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.web.servlet;
import javax.servlet.Filter;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.testutil.MockFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link Filter} registration.
*
* @author Andy Wilkinson
*/
public class FilterRegistrationIntegrationTests {
private AnnotationConfigEmbeddedWebApplicationContext context;
@After
public void cleanUp() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void normalFiltersAreRegistered() {
load(FilterConfiguration.class);
assertThat(this.context.getServletContext().getFilterRegistrations()).hasSize(1);
}
@Test
public void scopedTargetFiltersAreNotRegistered() {
load(ScopedTargetFilterConfiguration.class);
assertThat(this.context.getServletContext().getFilterRegistrations()).isEmpty();
}
private void load(Class<?> configuration) {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerConfiguration.class, configuration);
}
@Configuration
static class ContainerConfiguration {
@Bean
public TomcatEmbeddedServletContainerFactory servletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory(0);
}
}
@Configuration
static class ScopedTargetFilterConfiguration {
@Bean(name = "scopedTarget.myFilter")
public Filter myFilter() {
return new MockFilter();
}
}
@Configuration
static class FilterConfiguration {
@Bean
public Filter myFilter() {
return new MockFilter();
}
}
}
Loading…
Cancel
Save