Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Spring for real-world teams: Dependency Injection that Scales

Posted on March 24, 2010 By Luis Fernandez

“Dependency Injection is not a fad. It is a long breath for teams that want code they can reason about on a Wednesday at 3 a.m.”

Spring just keeps showing up in the places that matter. VMware owns SpringSource now, Oracle wrapped up the Sun deal, and everyone is watching where Java goes next. While the pundits argue, we still ship apps on Tomcat and friends, wire with DI, and try to keep Friday nights quiet. Spring 3 gave us a cleaner core, a leaner expression language, and first class Java config. The pitch is simple. Fewer surprises. Clear wiring. Testable code.

From a team desk, not a conference stage, the question is always the same. How does this scale when the codebase has years on it and five squads touch the same module. Dependency Injection that scales is about habits more than magic features. Where do beans live. Who owns the transaction boundary. Which bits can change without a deploy train derailment. Let’s talk the moves that pay rent in a real world shop.

Story one: shipping calm beats shipping clever

A few months ago we pulled a legacy order flow into a new service. The old code leaned on singletons with hidden lookups. The new bits used Spring 3 with @Configuration and normal constructors. The result was not a shrine to patterns. It was boring code that made on call life easy. When a payment gateway changed, we flipped a property and restarted one node. No mystery static state. No spelunking through global holders. This is where Spring earns its keep.

Story two: module lines draw people lines

Teams mirror the system. If your app context is one giant bowl, your team will trip over each other all week. We moved to parent child contexts in the web tier. Infra beans live in the parent. Web controllers sit in their servlet child. Feature teams get a slice, not the whole kitchen. Fewer bean name fights. Faster startup for tests. And when a module misbehaves, you can swap its child context without touching the rest.

Deep dive 1: constructor or setter, pick with intent

Constructor injection says “you cannot build me wrong.” Required collaborators go in the constructor. Optional ones can be setters. Keep it obvious. This helps in tests and keeps objects honest. In XML that looks like:

<bean id="invoiceService" class="com.acme.InvoiceService">
  <constructor-arg ref="taxCalculator"/>
  <constructor-arg ref="paymentGateway"/>
  <property name="auditLogger" ref="auditLogger"/>
</bean>

In Java config, same idea with fewer moving parts:

@Configuration
public class BillingConfig {

  @Bean
  public InvoiceService invoiceService(TaxCalculator taxCalculator,
                                       PaymentGateway paymentGateway) {
    InvoiceService s = new InvoiceService(taxCalculator, paymentGateway);
    s.setAuditLogger(auditLogger());
    return s;
  }

  @Bean public AuditLogger auditLogger() { return new AuditLogger(); }
}

Avoid field injection outside tests. You save a few keystrokes and pay with opaque wiring and awkward tests.

Deep dive 2: context boundaries that scale with people

Use a parent for cross cutting stuff like data sources, message brokers, caches. Children own web tier beans or feature sets. You get clear lines and better startup times. A classic web.xml split:

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:infra.xml classpath:services.xml</param-value>
</context-param>

<servlet>
  <servlet-name>app</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:web-app.xml</param-value>
  </init-param>
</servlet>

Name your beans, do not rely on auto names for shared stuff. When you must pick one among many, use @Qualifier and sleep better.

Deep dive 3: annotations, XML, and the sweet spot

Component scanning keeps the boilerplate low, but do not spray it across the whole classpath. Scan by package per module. Put wiring with business intent in Java config or XML close to the module. Keep env tweaks in properties. A small example:

@Configuration
@ComponentScan(basePackages = "com.acme.orders")
@PropertySource("classpath:orders-${env}.properties")
public class OrdersConfig {

  @Bean
  public DataSource dataSource(
      @Value("${db.url}") String url,
      @Value("${db.user}") String user,
      @Value("${db.pass}") String pass) {
    BasicDataSource ds = new BasicDataSource();
    ds.setUrl(url); ds.setUsername(user); ds.setPassword(pass);
    return ds;
  }
}

No official profiles yet, so swap properties per env and import the right snippets per deploy. Keep secrets out of source control, load from the box when you can.

Bonus for teams: tests that boot a thin slice. The Spring TestContext tricks make this easy:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {OrdersConfig.class})
@Transactional
public class OrderServiceTest {
  @Autowired OrderService svc;

  @Test public void charges_card() {
    svc.place(order());
  }
}

Keep the context light and you will not dread test startup.

A quick breath for the road

Spring for real world teams is not about worshiping a container. It is about making choices that scale with people and time. Constructor first. Clear module lines. Targeted scanning. Honest tests. The tools are here today. While the news cycle spins around corporate moves, we still have code to ship. Pick the habits that make next month easier, and your future self will buy you coffee.

Engineering Management Software Architecture Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes