Spring: убедитесь, что первый bean сначала инициализируется

У меня есть библиотека, выполняющая установку и настройку времени выполнения log4j (нет log4j.properties или log4j.xml). Я определил bean с классом MyLoggerFactory, и я хочу, чтобы это был первый bean, который должен быть инициализирован с помощью spring. Я видел, что проблема уже была подана с помощью spring, чтобы иметь поддержку для порядка инициализации, но мне было интересно, существует ли способ отметить bean как первый bean, который будет инициализирован контейнером spring

Ответ 1

Ваши варианты:

  1. Используйте аннотацию @DependsOn (доступную после Spring 3.0.x) или зависимую depends-on xml-атрибута и сделайте все классы, которые используют настроенные журналы, зависят от фабрики журналов
  2. Сделайте фабрику фактической фабрикой для лесорубов и введете регистраторы в бобы вместо прямого вызова фабрики - это по сути то же самое, что и вариант 1, за исключением того, что подразумевается зависимость. Это вариант, который я бы рекомендовал.
  3. Переместите код инициализации в часть вашего кода, где указан порядок вызова - метод main(), или ServletContextListener зарегистрированный до того, который инициализирует Spring.

Невозможно явно определить порядок инициализации весной и, вероятно, никогда не будет - нет способа определить полезную семантику для него, учитывая, что вы можете загружать многие файлы конфигурации контекста приложения, которые могут иметь конфликтующие упорядочения. Я еще не видел случая, когда желаемый заказ не мог быть достигнут путем рефакторинга вашего кода, чтобы лучше соответствовать шаблону инъекции зависимостей.

Ответ 2

Вы можете @Autowired @Configuration в главной @Configuration

@Configuration
@Import(BusinessConfig.class, EarlyBeans.class)
public class MainConfiguration {

    // The bean defined in EarlyBean will be loaded before 
    // most beans references by MainConfiguration, 
    // including those coming from BusinessConfig
    @Autowired
    EarlyBean earlyBean;

}

@Configuration
public class EarlyBeans {
    @Bean
    public Void earlyBean(ApplicationContext appContext) {
        // .getBeansOfType allows to call for beans which might not exist
        appContext.getBeansOfType(TechnicalBean.class);

        return null;
    }

}

Ответ 3

Это запрошенная функция, но не разрешена. Вы можете использовать зависящий, но слишком многословный. Следуйте ссылке для получения дополнительной информации: https://jira.springsource.org/browse/SPR-3948

Ответ 4

Вы можете разделить контекст вашего приложения как несколько и использовать импорт в основном контексте приложения. Сначала вы можете установить основные параметры среды в порядке импорта, а затем продолжить добавлять другие файлы.

Это может быть как показано ниже.

<!-- Import environment properties settings. -->
<import resource="Spring-Env.xml"/>
<!-- Import All the other Application contexts. -->
<import resource="Spring-MainApplicationContext.xml"/>