Enterprise Java

How to encapsulate Spring bean

As far as I know 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;

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;

public class UserService {
	private AddressService addressService;

	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;

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;

@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {
	private UserService userService;
	public void isPackagePrivateBeanCalled(){
		//GIVEN - spring context defined by Application class
		String actualUserDetails = userService.getUserDetails("john");
		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.

Reference: How to encapsulate Spring bean from our JCG partner Lubos Krnac at the Lubos Krnac Java blog blog.

Want to know how to develop your skillset to become a Java Rockstar?

Join our newsletter to start rocking!

To get you started we give you our best selling eBooks for FREE!


1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design


and many more ....


Receive Java & Developer job alerts in your Area

I have read and agree to the terms & conditions


Lubos Krnac

Lubos is a Java/JavaScript developer/Tech Lead and Automation enthusiast. His religion is to constantly improve his developments skills and learn new approaches. He believes TDD drives better design and nicely decoupled code. Past experience includes C++, Assembler and C#.
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Back to top button