1. Driving Forces

In a Spring application, injecting one bean into another bean is very common. However, sometimes it’s desirable to inject a bean into an ordinary object. For instance, we may want to obtain references to services from within an entity object.

Fortunately, achieving that isn’t as hard as it might look. The following sections will present how to do so using the @Configurable annotation and an AspectJ weaver.

2. The @Configurable Annotation

This annotation allows instances of the decorated class to hold references to Spring beans.

2.1. Defining and Registering a Spring Bean

Before covering the @Configurable annotation, let’s set up a Spring bean definition:

public class IdService {
    private static int count;

    int generateId() {
        return ++count;

This class is decorated with the @Service annotation; hence it can be registered with a Spring context via component scanning.

Here’s a simple configuration class enabling that mechanism:

public class AspectJConfig {

2.2. Using @Configurable

In its simplest form, we can use @Configurable without any element:

public class PersonObject {
    private int id;
    private String name;

    public PersonObject(String name) {
        this.name = name;

    // getters and other code shown in the next subsection

The @Configurable annotation, in this case, marks the PersonObject class as being eligible for Spring-driven configuration.

2.3. Injecting a Spring Bean into an Unmanaged Object

We can inject IdService into PersonObject, just as we would in any Spring bean:

public class PersonObject {
    private IdService idService;

    // fields, constructor and getters - shown in the previous subsection

    void generateId() {
        this.id = idService.generateId();

However, an annotation is only useful if recognized and processed by a handler. This is where AspectJ weaver comes into play. Specifically, the AnnotationBeanConfigurerAspect will act on the presence of @Configurable and does necessary processing.

3. Enabling AspectJ Weaving

3.1. Plugin Declaration

To enable AspectJ weaving, we need the AspectJ Maven plugin first:

    <!-- configuration and executions -->

And it requires some additional configuration:


The first required element is complianceLevel. A value of 17 sets both the source and target JDK versions to 17.

To inject a bean into an unmanaged object, we must rely on the AnnotationBeanConfigurerAspect class provided in the spring-aspects.jar. Since this is a pre-compiled aspect, we would need to add the containing artifact to the plugin configuration.

Note that such a referenced artifact must exist as a dependency in the project:


We can find the latest version of spring-aspects on Maven Central.

3.2. Plugin Execution

To instruct the plugin to weave all relevant classes, we need this executions configuration:


Notice the plugin’s compile goal binds to the compile lifecycle phase by default.

3.3. Bean Configuration

The last step to enable AspectJ weaving is to add @EnableSpringConfigured to the configuration class:

public class AspectJConfig {

The extra annotation configures AnnotationBeanConfigurerAspect, which in turn registers PersonObject instances with a Spring IoC container.

4. Testing

Now, let’s verify that the IdService bean has been successfully injected into a PersonObject:

@ContextConfiguration(classes = AspectJConfig.class)
public class PersonUnitTest {
    public void givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectlySet() {
        PersonObject personObject = new PersonObject("Baeldung");
        assertEquals(1, personObject.getId());
        assertEquals("Baeldung", personObject.getName());

5. Injecting a Bean Into a JPA Entity

From the Spring container’s point of view, an entity is nothing but an ordinary object. As such, there’s nothing special about injecting a Spring bean into a JPA entity.

However, since injecting into JPA entities is a typical use case, let’s cover it in more detail.

5.1. Entity Class

Let’s start with the entity class’s skeleton:

@Configurable(preConstruction = true)
public class PersonEntity {
    private int id;
    private String name;

    public PersonEntity() {

    // other code - shown in the next subsection

Notice the preConstruction element in the @Configurable annotation: it enables us to inject a dependency into the object before it’s fully constructed.

5.2. Service Injection

Now we can inject IdService into PersonEntity, similar to what we did with PersonObject:

// annotations
public class PersonEntity {
    private IdService idService;

    // fields and no-arg constructor

    public PersonEntity(String name) {
        id = idService.generateId();
        this.name = name;

    // getters

The @Transient annotation is used to tell JPA that idService is a field not to be persisted.

5.3. Test Method Update

Finally, we can update the test method to indicate that the service can be injected into the entity:

public void givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectlySet() {
    // existing statements

    PersonEntity personEntity = new PersonEntity("Baeldung");
    assertEquals(2, personEntity.getId());
    assertEquals("Baeldung", personEntity.getName());

6. Caveats

Although it’s convenient to access Spring components from an unmanaged object, it’s often not a good practice to do so.

The problem is that unmanaged objects, including entities, are usually part of the domain model. These objects should carry data only to be reusable across different services.

Injecting beans into such objects could tie components and objects together, making it harder to maintain and enhance the application.

7. Conclusion

This tutorial has walked through the process of injecting a Spring bean into an unmanaged object. It also mentioned a design issue associated with dependency injection into objects.

The implementation code can be found over on GitHub.

Course – LSD (cat=Persistence)

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

res – Persistence (eBook) (cat=Persistence)
1 Comment
Inline Feedbacks
View all comments
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.