DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Trending

  • AI Agents Need an Identity Plane: Rethinking Enterprise Authorization for Autonomous Software
  • YAGNI in the Age of AI Coding
  • How to Migrate From LangChainGo to Genkit Go
  • Should Developers Switch From SQLite to DuckDB?

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Frameworks
  4. How to Encapsulate a Spring Bean

How to Encapsulate a Spring Bean

By 
Lubos Krnac
·
Jan. 03, 15 · Interview
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
14.0K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

As far as I know the Spring Framework doesn’t provide any mechanism to encapsulate Spring beans other than having separate contexts. So when you have public class registered in Spring’s Inversion of Control container, it can be autowired in any Spring bean from same context configuration. This is very powerful but it is also very dangerous. Developers can easily couple beans together. With lack of discipline team can easily shoot themselves in foot. Unfortunately I was working on one monolithic project where team was shooting themselves into foot with submachine gun. Wiring was breaking layering rules often. Nobody could easily follow what is dependent on what. Bean dependency graph was just crazy. This is serious concern in bigger applications.

Luckily there is one simple way how to encapsulate Spring bean. Spring works nicely with default access modifier on class level. So you can create package private bean, which can be used only within current package. Simple and powerful. Let’s take a look at example:

package net.lkrnac.blog.spring.encapsulatebean.service;
 
import org.springframework.stereotype.Service;
 
@Service
class AddressService {
    public String getAddress(String userName){
        return "3 Dark Corner";
    }
}

This simple bean is wired into another one within same package:

package net.lkrnac.blog.spring.encapsulatebean.service;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class UserService {
    private AddressService addressService;
 
    @Autowired
    public UserService(AddressService addressService) {
        this.addressService = addressService;
    }
     
    public String getUserDetails(String userName){
        String address = addressService.getAddress(userName);
        return String.format("User: %s, %s", userName, address);
    }
}

Main context just scans both beans:

package net.lkrnac.blog.spring.encapsulatebean;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
}

Here is test to prove it works fine:

package net.lkrnac.blog.spring.encapsulatebean;
 
import net.lkrnac.blog.spring.encapsulatebean.service.UserService;
 
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {
    @Autowired
    private UserService userService;
     
    @Test
    public void isPackagePrivateBeanCalled(){
        //GIVEN - spring context defined by Application class
         
        //WHEN
        String actualUserDetails = userService.getUserDetails("john");
         
        //THEN
        Assert.assertEquals("User: john, 3 Dark Corner", actualUserDetails);
    }
}

I believe everybody should consider using default access modifier for every new bean. Obviously there would need to be some public bean within each package. But at not every bean. Source code is on GitHub.

Spring Framework

Published at DZone with permission of Lubos Krnac. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook