Spring bean дважды инициализируется в конфигурации java

Я создал приложение Spring с использованием spring -security с конфигурацией на основе Java. Я также включил в свой проект файл jar (созданный мной). Проблема, с которой я столкнулся: - Мне нужно написать @ComponentScan (basePackages = {"com.mypackage"}) в обоих классах (SpringConfig.java и SecurityConfig.java), что приводит к двойной инициализации beans. Удаление любого из @componentscan приводит к ошибке: - Ошибка при создании bean-компонента с именем securityConfig..

Ниже приведены мои классы Java.

SpringConfig.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");
    }
}

SecurityConfig.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();
    }
  }
}

MyController.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-------");
    }
}

Если у вас точно такой же @ComponentScan, то bean-компоненты будут созданы дважды (при загрузке как в ContextLoaderListener, так и в DispatcherServlet). Не делайте этого, укажите, что вы хотите загрузить и загрузить один раз, также в отношении памяти и предотвращения странных транзакционных проблем.

M. Deinum 12.04.2018 11:33
0
1
2 059
2

Ответы 2

Компоненты будут настроены и созданы дважды, потому что оба контекста приложения сканируют один и тот же пакет com.mypackage. Одно из решений - отделить пакет bean-компонентов SpringConfig от пакета bean-компонентов SecurityConfig. быть как можно более конкретным в значении пакета @ComponentScan

Вы настроили определения bean-компонентов в несколько классов @Configuration. Мое предложение - объединить классы @ Конфигурация с @Импортировать в одном месте. Теперь вы можете применять @ComponentScan (basePackages = {"com.mypackage"}) в одном месте, и контекст также загружает bean-компонент только один раз.

The @Импортировать annotation provides just this kind of support, and it is the direct equivalent of the элемент, найденный в XML-файлах Spring beans. Пожалуйста, обратитесь по этой ссылке - https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s03.html

Другие вопросы по теме