---
title: Spring Circular Dependencies
url: https://blog.octoperf.com/spring-circular-dependencies/
date: '2018-02-15'
authors:
- jloisel
categories:
- Development
tags:
- Java
- Spring
description: Spring Autowiring loop, also known as circular references, can give headaches. Get actionable insights on how to solve them through real code examples.
---

# Spring Circular Dependencies

I know you've been there, like me:

- I Have a circular dependency in Spring and my application fails to launch. How to solve this?

The typical exception thrown by [Spring](https://spring.io) is the following:

> 'org.springframework.security.authenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference?

And, **It does not give much details**. So, let's see how we can break the **circular dependency cycle** and save some sanity!


## Understand the Issue

Let's take a very simple example to illustrate the issue. Here is part of our code handling the application permissions.

```java
public interface PermissionByObject {

  boolean accept(Object targetObject, String permission);

  boolean test(User user, Object targetObject, String permission);
}

```

The `SpringPermissionEvaluator` then requires all the `PermissionByObject` implementations to be injected via [collection autowiring](https://blog.octoperf.com/spring-autowiring-by-example/#collection-autowiring). 

```java

final class SpringPermissionEvaluator implements SystemPermissionEvaluator {
  List<PermissionByObject> byObject;

  SpringPermissionEvaluator(final List<PermissionByObject> byObjects) {
    super();
    this.byObject = requireNonNull(byObjects);
  }

  @Override
  public boolean hasPermission(
    final Authentication authentication,
    final Object targetObject,
    final Object key) {
    final User user = (User) authentication.getPrincipal();

    final String permission = valueOf(key);
    return byObject
      .stream()
      .filter(p -> p.accept(targetObject, permission))
      .anyMatch(p -> p.test(user, targetObject, permission));
  }
}
```

Suppose now that we have the following implementation named `WorkspaceByObject`:

```java
@Component
final class WorkspaceByObject implements PermissionByObject {
  
  private final WorkspacePermission delegate;

  WorkspaceByObject(WorkspacePermission delegate) {
    this.delegate = checkNotNull(delegate);
  }

  @Override
  public boolean accept(final Object targetObject, final String permission) {
    return targetObject instanceof Workspace;
  }

  @Override
  public boolean test(final User user, final Object targetObject, final String permission) {
    // do something with the evaluator like delegating the call
  }

}
```

We have a **circular dependency** here:

* `SystemPermissionEvaluator` requires all `PermissionByObject` on construction,
* `WorkspaceByObject` implements `PermissionByObject` and requires `SystemPermissionEvaluator` on construction.

We're going to explore the ways we can solve this issue.

## Field Autowiring

The first and most obvious solution is to prevent the `WorkspaceByObject` from requiring the `SystemPermissionEvaluator` upon construction by using **Field injection**.

```java
@Component
final class WorkspaceByObject implements PermissionByObject {
  @Autowired
  SystemPermissionEvaluator evaluator;

  @Override
  public boolean accept(final Object targetObject, final String permission) {
    return targetObject instanceof Workspace;
  }

  @Override
  public boolean test(final User user, final Object targetObject, final String permission) {
    // do something with the evaluator like delegating the call
  }

}
```
*SystemPermissionEvaluator injected via Field Injection*

## Setter Autowiring

Or **Setter Injection**:

```java
@Component
final class WorkspaceByObject implements PermissionByObject {
  
  SystemPermissionEvaluator evaluator;

  @Override
  public boolean accept(final Object targetObject, final String permission) {
    return targetObject instanceof Workspace;
  }

  @Override
  public boolean test(final User user, final Object targetObject, final String permission) {
    // do something with the evaluator like delegating the call
  }

  public void setEvaluator(final SystemPermissionEvaluator evaluator) {
    this.evaluator = evaluator;
  }
}
```
*SystemPermissionEvaluator injected via Setter Injection*

Another solution would be to apply the same trick to the `SystemPermissionEvaluator`. Why does it work? Because **Spring can inject the dependencies after construction**.

## Using @Lazy

The [@Lazy](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Lazy.html) annotation allows Spring to inject a [Java Proxy](https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html) of your bean, instead of the bean itself. It can resolves the cycle by instantiating the beans when a method on it is called.

```java
@Component
final class WorkspaceByObject implements PermissionByObject {
  
  private final SystemPermissionEvaluator evaluator;

  WorkspaceByObject(@Lazy final SystemPermissionEvaluator evaluator) {
    super();
    this.evaluator = checkNotNull(evaluator);
  }

  @Override
  public boolean accept(final Object targetObject, final String permission) {
    return targetObject instanceof Workspace;
  }

  @Override
  public boolean test(final User user, final Object targetObject, final String permission) {
    // do something with the evaluator like delegating the call
  }
}
```

Because `@Lazy` proxyfies your bean, calls to your service are done through reflection, **thus being 2x slower than direct calls**. Therefore, I would recommend using `@Lazy` only when nothing else is possible.

## Using @PostConstruct

[PostConstruct](https://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html) can be used to annotate a method which is then called once the bean has been properly autowired. It can be effectively used to fix a circular dependency, although you should be aware it's pretty ugly to do so.

We can do so by altering the permission interface:

```java
public interface PermissionByObject {

  void setPermissionEvaluator(SystemPermissionEvaluator evaluator);

  boolean accept(Object targetObject, String permission);

  boolean test(User user, Object targetObject, String permission);
}
```

As you can see, this will pretty much affect every single `PermissionByObject` implementation even if it's not using the `SystemPermissionEvaluator`...

Then, we'll do this in the `SystemPermissionEvaluator`:

```java

final class SpringPermissionEvaluator implements SystemPermissionEvaluator {
  List<PermissionByObject> byObject;

  SpringPermissionEvaluator(final List<PermissionByObject> byObjects) {
    super();
    this.byObject = requireNonNull(byObjects);
  }

  @PostConstructor 
  void postConstruct() {
    for (final PermissionByObject p : byObjects) {
      p.setPermissionEvaluator(this);
    }
  }
}
```

Needless to say, this solution is exposing the internals of a specific permission to everyone. It's also affecting permissions which don't need the `SystemPermissionEvaluator` being injected. 

So, what can be do to solve this issue properly?

## Using @Configuration

Another solution is to register the `PermissionByObject` instances into the `SystemPermissionEvaluator` using an external Spring Configuration **within the same package**. The key is to keep the registering logic **invisible to external callers**.

```java

@Service
final class SpringPermissionEvaluator implements SystemPermissionEvaluator {
  private final List<PermissionByObject> byObject = new ArrayList<>();

  void register(final PermissionByObject p) {
    byObject.add(p);
  }
}

@Configuration
class PermissionConfig {

  PermissionConfig(final SystemPermissionEvaluator evaluator, final List<PermissionByObject> permissions) {
    super();
    permissions.forEach(evaluator::register);
  }
}

```

By doing this, the **cycle is broken down**. Both permission evaluator and permissions can be instantiated independently.

## Changing the Code

A circular dependency issue should be an alarm screaming: **Hey, there is something wrong with your code architecture!** Of course, it's not always possible to fix the issue by yourself. It may happen due to a badly designed library you are depending on. 

After figuring it out, in fact the `WorkspaceByObject` has been rewritten (as well as other parts of the permission system) to completely avoid injecting the `SystemPermissionEvaluator` at all!

## Final Words

Always consider redesigning your code before deep diving into fancy solutions to fix spring circular dependencies issues. Use the methods described here as last resort when nothing else is possible. 

Remember **Spring isn't difficult**! There is a solution to every problem related to Spring, and chances are that you are not the single one experiencing those issues. Always look on [Spring StackOverflow](https://stackoverflow.com/questions/tagged/spring) to see if someone else has had the same issue.
