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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
