02 — Getting Started
Auto-Configuration
rulii-spring ships with a single @AutoConfiguration class — RuleConfig — that sets up everything you need. It's registered through Spring Boot's META-INF/spring/AutoConfiguration.imports file, so it activates automatically when the library is on the classpath.
How It Works
Every bean defined by RuleConfig is annotated with @ConditionalOnMissingBean. This means you can override any bean by declaring your own — Spring Boot will skip the default and use yours instead.
Auto-Configured Beans
RuleConfig creates the core beans below, plus four new beans in 2.0.0 (covered afterwards). Here's each one, what it does, and how to replace it.
1. BindingMatchingStrategy
Controls how rule parameters are matched to bindings at runtime. The default uses the standard matching strategy.
@Bean
@ConditionalOnMissingBean(BindingMatchingStrategy.class)
public BindingMatchingStrategy bindingMatchingStrategy() {
return BindingMatchingStrategy.builder().build();
}
2. ParameterResolver
Resolves method parameters when invoking rule conditions and actions.
@Bean
@ConditionalOnMissingBean(ParameterResolver.class)
public ParameterResolver parameterResolver() {
return ParameterResolver.builder().build();
}
3. MessageResolver
Resolves messages for rule violations from Spring's Environment. This is a Spring-specific implementation that reads message codes from application.properties.
@Bean
@ConditionalOnMissingBean(MessageResolver.class)
public MessageResolver messageResolver(Environment environment) {
return new SpringEnvironmentMessageResolver(environment);
}
4. MessageFormatter
Formats resolved message strings, substituting placeholders with runtime values.
@Bean
@ConditionalOnMissingBean(MessageFormatter.class)
public MessageFormatter messageFormatter() {
return MessageFormatter.builder().build();
}
5. ObjectFactory
Creates rule instances. When Spring's AutowireCapableBeanFactory is available, this uses SpringObjectFactory to enable constructor injection. Otherwise falls back to rulii's default factory.
@Bean(name = BeanNames.OBJECT_FACTORY_NAME)
@ConditionalOnMissingBean(ObjectFactory.class)
public ObjectFactory objectFactory(BeanFactory beanFactory) {
if (beanFactory instanceof AutowireCapableBeanFactory ctx) {
return new SpringObjectFactory(ctx);
}
return ObjectFactory.builder().build();
}
6. ConverterRegistry
Manages type converters for rule parameters. Automatically picks up any Spring Converter beans and wraps Spring's ConversionService with a SpringConverterAdapter.
@Bean(name = BeanNames.SPRING_CONVERTER_REGISTRY)
@ConditionalOnMissingBean(ConverterRegistry.class)
public ConverterRegistry converterRegistry(
@Autowired(required = false) Set<Converter<?, ?>> converters,
@Autowired(required = false) ConversionService conversionService,
@Value("${rulii.converts.registerDefaults:true}") boolean registerDefaults) {
// Registers defaults, custom converters, and Spring ConversionService
}
7. RuleRegistry
A Spring-backed registry that looks up rules directly from the application context. Uses SpringRuleRegistry when a ListableBeanFactory is available.
@Bean(BeanNames.RULE_REGISTRY)
@ConditionalOnMissingBean(RuleRegistry.class)
public RuleRegistry ruleRegistry(
@Autowired(required = false) ListableBeanFactory ctx) {
if (ctx != null) return new SpringRuleRegistry(ctx);
return RuleRegistry.builder().build();
}
8. RuleContextOptions
Bundles all the above beans into a single options object for rule execution. Includes a fixed thread pool for async execution and the system clock.
@Bean
@ConditionalOnMissingBean(RuleContextOptions.class)
public RuleContextOptions ruleContextOptions(...) {
return new SpringEnabledRuleContextOptions(
matchingStrategy, parameterResolver, messageFormatter,
converterRegistry, objectFactory, messageResolver,
Executors.newFixedThreadPool(Math.max(2, Runtime.getRuntime().availableProcessors())),
Clock.systemDefaultZone(), Locale.getDefault());
}
9. RuleBeanDefinitionRegistryPostProcessor
A fallback post-processor that automatically scans for rules when @RuleScan is not present. It uses AutoConfigurationPackages to determine the base packages. This bean is only created if no RuleRegistrarMetaInfo bean exists (which @RuleScan registers).
New Beans in 2.0.0
rulii.executorService
A bounded thread pool (work queue of 1000, caller-runs policy) used for async rule and RuleFlow execution, shut down with the application context. It is overridden by name: define your own bean named rulii.executorService to replace it — unrelated ExecutorService beans are deliberately ignored.
Tracer
Auto-configured with every RuliiListener, RuleListener, RuleSetListener, and RuleFlowListener bean found in the context. A bean that implements several listener interfaces is registered exactly once.
ScriptProcessorManager & ScriptTextResolverConfigurer
The script manager wires all discovered ScriptProcessorFactory beans (including SpEL). The resolver configurer enables ${property:default} environment placeholders inside script text; disable it with rulii.scripts.resolvePlaceholders=false.
Overriding a Bean
To replace any auto-configured bean, just define your own. For example, to provide a custom MessageResolver:
@Configuration
public class MyRuleConfig {
@Bean
public MessageResolver messageResolver() {
return new MyCustomMessageResolver();
}
}
Because RuleConfig uses @ConditionalOnMissingBean, your bean takes priority and the default is skipped entirely.