Reputation: 3771
I have a library doing runtime setup and configuration of log4j (no log4j.properties or log4j.xml). I have defined a bean with class called MyLoggerFactory and I want this to be the first bean to be initialised using spring. I have seen that an issue has already been filed with spring to have support for order of initialisation but I was wondering whether there was a way to mark a bean as the first bean to be initialised by spring container?
Upvotes: 75
Views: 152015
Reputation: 49
in addition to the mentioned points, you can use SpringApplicationRunListener interface for config different application life cycles. you can config ConfigurableBootstrapContext in starting, environmentPrepared phases furthermore you can config ConfigurableApplicationContext in contextPrepared, contextLoaded, started, ready, failed phases.
for your case:
Called once the ApplicationContext has been created and prepared, but before sources have been loaded.
default void contextPrepared(ConfigurableApplicationContext context) { }
public class AppConfiguration implements SpringApplicationRunListener {
public void contextPrepared(ConfigurableApplicationContext context) {
var provider = new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
return super.isCandidateComponent(beanDefinition) || beanDefinition.getMetadata().isAbstract();
}
};
// you are gonna find specific class such as the classes marked by Qualifier
provider.addIncludeFilter(new AnnotationTypeFilter(Qualifier.class, true, true));
final Set<BeanDefinition> classes = provider.findCandidateComponents("com.tosan");
classes.forEach(beanDefinition -> {
try {
//add bean to context
context.getBeanFactory().registerSingleton(Objects.requireNonNull(beanDefinition.getBeanClassName()), new YourBeens());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
}
}
Don't forget to put the listener in src/main/resources/META-INF/spring.factories like below otherwise the listener will not run.
org.springframework.boot.SpringApplicationRunListener=com.example.AppConfiguration
Upvotes: 0
Reputation: 2217
You can @Autowired an @Configuration in the main @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
EarlyBeans earlyBeans;
}
@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;
}
}
Upvotes: 20
Reputation: 39950
Your options are:
@DependsOn
annotation(available after spring 3.0.x) or depends-on
xml-attribute and make all classes that use the configured loggers depend on the logger factorymain()
method, or a ServletContextListener
registered before the one that initializes Spring.There is no way to explicitly define initialisation order in Spring and likely never will be – there's no way to define useful semantics for it considering you can load many application context configuration files which might have conflicting orderings. I've yet to see a case where the desired ordering couldn't be achieved by refactoring your code to better conform to the dependency injection pattern.
Upvotes: 56
Reputation: 425
You can split your application context as multiple and use import in main application context. You can put the main environment settings first in the order of import and then continue adding other files.
It could be like below.
<!-- Import environment properties settings. -->
<import resource="Spring-Env.xml"/>
<!-- Import All the other Application contexts. -->
<import resource="Spring-MainApplicationContext.xml"/>
Upvotes: 1
Reputation: 13792
This is a feature requested but not resolved. You can use depends-on but is too verbose. Follow tis link for more information: https://jira.springsource.org/browse/SPR-3948
Upvotes: 3