避免不必要的Spring配置组件扫描

在堆栈溢出中遇到了一个有趣的问题。 Brett Ryan有问题,Spring Security配置被初始化了两次。 当我查看他的代码时,我发现了问题所在。 让我展示显示代码。

他有相当标准的Spring应用程序(不使用Spring Boot)。 使用基于Spring的AbstractAnnotationConfigDispatcherServletInitializer更现代的Java servlet配置。

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends
		AbstractAnnotationConfigDispatcherServletInitializer {


    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SecurityConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

}

如您所见,有两个配置类:

  • SecurityConfig –保存Spring Security配置
  • WebConfig – Spring的主要IoC容器配置
package net.lkrnac.blog.dontscanconfigurations;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        System.out.println("Spring Security init...");
        auth
                .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }

}
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "net.lkrnac.blog.dontscanconfigurations")
public class WebConfig extends WebMvcConfigurerAdapter {

}

注意WebConfig的组件扫描。 这是扫描软件包,所有三个类都位于该软件包中。 在servlet容器上运行此命令时,将文本“ Spring Security init…”写入控制台两次。 这意味着SecurityConfig配置被加载两次。 它已加载:

  1. 在方法AppInitializer.getRootConfigClasses()的Servlet容器初始化期间
  2. 通过类WebConfig组件扫描

为什么? 我在Spring的文档中找到了这种解释

请记住, @Configuration类使用@Component进行元注释 ,因此它们是组件扫描的候选对象!

因此,这是Spring的功能,因此我们要避免Servlet配置使用的Spring @Configuration组件扫描。 Brett Ryan独立地发现了这个问题,并在提到的Stack Overflow问题中展示了他的解决方案:

@ComponentScan(basePackages = "com.acme.app",
               excludeFilters = {
                   @Filter(type = ASSIGNABLE_TYPE,
                           value = {
                               WebConfig.class,
                               SecurityConfig.class
                           })
               })

我不喜欢这种解决方案。 注释对我来说太冗长了。 另外,一些开发人员可以创建新的@Configuration类,而忘记将其包含在此过滤器中。 我宁愿指定将被Spring的组件扫描排除的特殊软件包。

翻译自: https://www.javacodegeeks.com/2014/12/avoid-unwanted-component-scanning-of-spring-configuration.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值