03 — Getting Started
Rule Scanning & Discovery
rulii-spring automatically discovers your @Rule classes and registers them as Spring beans. There are two ways this happens: explicit scanning with @RuleScan, or automatic fallback scanning.
@RuleScan (Recommended)
Place @RuleScan on your main application class or any @Configuration class. It accepts an array of base packages to scan.
@SpringBootApplication
@RuleScan(scanBasePackages = {"com.example.rules", "com.example.validation"})
public class MyApp { }
If you omit scanBasePackages, the scanner defaults to the package of the annotated class:
// Scans com.example and all sub-packages
package com.example;
@SpringBootApplication
@RuleScan
public class MyApp { }
How Scanning Works
Under the hood, @RuleScan triggers a RuleRegistrar (an ImportBeanDefinitionRegistrar). Here's the flow:
RuleRegistrarreads thescanBasePackagesattribute from@RuleScan- A
RuleBeanDefinitionScanner(extendingClassPathBeanDefinitionScanner) scans those packages for classes annotated with@Rule - Each discovered class is wrapped in a
BeanDefinitionthat usesRuleBeanBuilder.build()as its factory method - The bean is registered under the rule's name (derived from the class by
ClassBasedRuleBuilder.getRuleName()) - A
RuleRegistrarMetaInforecord is stored, tracking the scanned packages and rule count
Automatic Fallback Scanning
If you don't use @RuleScan, rulii-spring still tries to find your rules. The auto-configured RuleBeanDefinitionRegistryPostProcessor kicks in and uses Spring Boot's AutoConfigurationPackages to determine base packages.
This works, but you'll see a log message recommending explicit @RuleScan usage. The fallback exists for convenience; explicit scanning gives you full control over which packages are included.
Tip
Always prefer explicit @RuleScan in production applications. It's faster (scans only what you specify) and makes your configuration self-documenting.
What Gets Scanned
The scanner looks exclusively for classes annotated with rulii's @Rule annotation. A typical rule class looks like this:
package com.example.rules;
@Rule
public class AgeVerificationRule {
@Given
public boolean isAdult(Integer age) {
return age != null && age >= 18;
}
@Then
public void allow() {
// approved
}
@Otherwise
public void deny() {
// rejected
}
}
After scanning, this rule is available as a Spring bean named "AgeVerificationRule" (the name is derived from the class). You can look it up through the RuleRegistry or inject it directly.
Multiple @RuleScan Locations
You can specify multiple packages in a single @RuleScan annotation. All packages and their sub-packages are scanned recursively.
@RuleScan(scanBasePackages = {
"com.example.rules.eligibility",
"com.example.rules.pricing",
"com.example.rules.compliance"
})