How Spring Framework Uses Interpreter, Builder, Factory Method, and Abstract Factory Patterns

This article explains how Spring Framework applies four classic design patterns—Interpreter, Builder, Factory Method, and Abstract Factory—to simplify object creation and configuration, providing clear Java code examples, Spring bean definitions, and a discussion of their roles within the framework.

Programmer DD
Programmer DD
Programmer DD
How Spring Framework Uses Interpreter, Builder, Factory Method, and Abstract Factory Patterns

Introduction

Design patterns help developers follow proven programming practices, and the popular Spring Framework incorporates several of them. This article introduces four patterns—Interpreter, Builder, Factory Method, and Abstract Factory—showing how they are used inside Spring with concrete Java examples.

Interpreter Pattern

Spring Expression Language (SpEL) is an interpreter that parses and evaluates string expressions at runtime. The example below demonstrates how SpEL can modify an object's property through an expression evaluated in a specific context.

Writer writer = new Writer();
writer.setName("Writer's name");
StandardEvaluationContext context = new StandardEvaluationContext(subscriberContext);
context.setVariable("name", "Overriden writer's name");
ExpressionParser parser = new SpelExpressionParser();
parser.parseExpression("name = #name").getValue(context);
System.out.println("writer's name is : " + writer.getName());

The output prints “Overriden writer’s name”, showing that the expression is interpreted only by the SpEL parser because of the provided context.

Builder Pattern

The Builder pattern separates the construction of a complex object from its representation, allowing step‑by‑step configuration. In Spring, the BeanDefinitionBuilder class follows this approach.

Programmer programmer = new Programmer.ProgrammerBuilder()
    .setFirstName("F")
    .setLastName("L")
    .setCity("City")
    .setZipCode("0000A")
    .setLanguages(new String[]{"bash", "Perl"})
    .setProjects(new String[]{"CRM system", "CMS system for government"})
    .build();

Spring’s own BeanDefinitionBuilder offers fluent methods such as setParentName, setFactoryMethod, addConstructorArgValue, and addPropertyValue to hide the complexity of bean definition creation.

Factory Method Pattern

The Factory Method pattern creates objects through a static method rather than a constructor. The following simple Java example mimics a Spring factory method:

Meal fruit = Meal.valueOf("banana");
Meal vegetable = Meal.valueOf("carrot");
assertTrue("Banana should be fruit", fruit.getType().equals("fruit"));
assertTrue("Carrot should be vegetable", vegetable.getType().equals("vegetable"));

In Spring XML, the same idea is expressed with the factory-method attribute:

<bean id="welcomerBean" class="com.mysite.Welcomer" factory-method="createWelcomer">
    <constructor-arg ref="messagesLocator"/>
</bean>

The corresponding static factory method decides which message key to use based on the time of day:

public static Welcomer createWelcomer(MessageLocator messagesLocator) {
    Calendar cal = Calendar.getInstance();
    String msgKey = "welcome.pm";
    if (cal.get(Calendar.AM_PM) == Calendar.AM) {
        msgKey = "welcome.am";
    }
    return new Welcomer(messagesLocator.getMessageByKey(msgKey));
}

Abstract Factory Pattern

The Abstract Factory groups related factories and products. The example below defines an abstract Kitchen with methods to obtain a meal and a dessert, and a concrete KitchenFactory that returns different product implementations based on a preference string.

abstract class Kitchen {
    abstract KitchenMeal getMeal(String preference);
    abstract KitchenMeal getDessert(String preference);
}

class KitchenFactory extends Kitchen {
    @Override
    KitchenMeal getMeal(String preference) {
        if (preference.equals("F.1")) return new FastFoodMeal();
        else if (preference.equals("P.1")) return new ProteinMeal();
        else return new VegetarianMeal();
    }
    @Override
    KitchenMeal getDessert(String preference) {
        if (preference.equals("I.1")) return new IceCreamMeal();
        return null;
    }
}

abstract class KitchenMeal { abstract String getName(); }
class ProteinMeal extends KitchenMeal { @Override String getName() { return "protein meal"; } }
class FastFoodMeal extends KitchenMeal { @Override String getName() { return "fast-food meal"; } }
class VegetarianMeal extends KitchenMeal { @Override String getName() { return "vegetarian meal"; } }
class IceCreamMeal extends KitchenMeal { @Override String getName() { return "ice-cream"; } }

In Spring, the BeanFactory interface represents the abstract factory, while implementations such as DefaultListableBeanFactory act as concrete factories that produce beans (objects) on demand.

Conclusion

The first article of this series showed how design patterns improve code organization. Here we saw that Spring uses the Interpreter pattern for SpEL, and the three creational patterns—Builder, Factory Method, and Abstract Factory—to simplify object creation, configuration, and dependency injection throughout the framework.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaspringinterpreterAbstract FactoryFactory MethodBuilder
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.