我创建了一个使用spring-security和基于java的配置的spring应用程序。我还在我的项目中包含一个 jar 文件(由我创建(。我面临的问题是:- 我必须在两个类(SpringConfig.java和SecurityConfig.java(中编写@ComponentScan(basePackages = {"com.mypackage"}(,这会导致两次初始化bean。删除@componentscan中的任何一个都会导致错误:- 创建名为"securityConfig"的 bean 时出错。
下面是我的 java 类。
弹簧配置.java
package com.mypackage.config;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.mypackage"})
public class SpringConfig extends WebMvcConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SpringConfig.class);
@PostConstruct
public void init(){
logger.debug("Spring Config initialized");
}
}
安全配置.java
package com.mypackage.config;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = {"com.mypackage"})
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
//This Configuration class is in my jar file.
// with package starting with same name com.mypackage
@Autowired
com.mypackage.frameworks.config.Configuration config;
@PostConstruct
public void init(){
logger.debug("Security config initiaziled");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles("USER");
} catch (Exception e) {
e.printStackTrace();
}
}
}
我的控制器.java
package com.mypackage.controller;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
@PostConstruct
public void init(){
logger.debug("-------Controller created-------");
}
}
您已将 Bean 定义配置为多个@Configuration类。我的建议是 - 将@Configuration类与@Import聚合到一个地方。现在,您可以在一个地方应用 @ComponentScan(basePackages = {"com.mypackage"}(,并且上下文也只加载 bean 一次。
@Import注解正好提供了这种支持,它直接等同于 Spring bean XML 文件中的元素。请参考此链接 - https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s03.html
Beans 将被配置和创建两次,因为两个应用程序上下文都扫描同一个包"com.mypackage"。一种解决方案是将 SpringConfig bean 包与 SecurityConfig bean 包分开。在包值中尽可能具体@ComponentScan