08 — Advanced

Spring Context Bindings

SpringContextBindingLoader makes every Spring bean available as a read-only binding in rulii's binding system. This lets your rules access any bean in the application context by name — without explicit injection.

How It Works

The loader implements BindingLoader<ListableBeanFactory>. When you call load(), it iterates through every bean definition in the Spring context and creates a binding for each one.

public class SpringContextBindingLoader
        implements BindingLoader<ListableBeanFactory> {

    public void load(Bindings bindings, ListableBeanFactory factory) {
        for (String beanName : factory.getBeanDefinitionNames()) {
            // Creates a lazy, read-only binding for each bean
            Supplier supplier = () -> factory.getBean(beanName);
            // ...
        }
    }
}

Key Characteristics

Lazy Loading

Beans are not fetched until the binding is actually accessed. The getter is a Supplier that calls factory.getBean() on demand.

Read-Only

Bindings created by the loader have no setter. Rules can read Spring beans but cannot replace them through the binding system.

Non-Editable

Each binding is marked as non-editable, protecting the Spring context from unintended modifications.

All Beans

Every bean definition in the context is loaded, including infrastructure beans. The binding name matches the bean name.

Usage Example

Load Spring beans into a Bindings instance and pass them to a rule context:

@Service
public class RuleRunner {

    private final ListableBeanFactory beanFactory;

    @Autowired
    public RuleRunner(ListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public void runWithSpringBeans(Rule rule) {
        Bindings bindings = Bindings.builder().build();

        // Load all Spring beans as bindings
        SpringContextBindingLoader loader = new SpringContextBindingLoader();
        loader.load(bindings, beanFactory);

        // Now the rule can reference any Spring bean by name
        rule.run(bindings);
    }
}

Inside the rule, any parameter whose name matches a Spring bean name will be resolved from the loaded bindings. For example, if you have a userRepository bean, a rule parameter named userRepository will receive it.

Note

Loading the entire Spring context as bindings gives rules broad access. For tighter control, load only specific beans into your bindings manually instead of using the full context loader.