Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring injection with Java's Optional

When trying to inject an Optional<T>, Spring never calls my bean, and instead injects an Optional.empty().

Here is some sample code:

@Configuration
public class Initialize {

    @Value("optionalValue")
    private String testString;

    @Bean (name = "getOptionalString")
    public Optional<String> getOptionalString() {
        return Optional.of(this.testString); //breakpoint put here, is never called
    }
}

@Component
public class Test {

    public Test(@Qualifier("getOptionalString") Optional<String> optional) {
      // optional's value is Optional.empty() here
    }

I noticed that (by putting a breakpoint) the @Bean is never called. If I were to remove the Optional<String>, and simply return a String, then it works!

I know Spring has its own optional dependency but I am perplexed as to why this doesn't work (whatever I read online says it should), and I also don't understand how it initialized it to Optional.empty()?

like image 503
Tiberiu Avatar asked Oct 23 '19 18:10

Tiberiu


People also ask

Is @autowired optional?

Before Spring 4.3, we had to add an @Autowired annotation to the constructor. With newer versions, this is optional if the class has only one constructor.

Why Spring field injection is not recommended?

The reasons why field injection is frowned upon are as follows: You cannot create immutable objects, as you can with constructor injection. Your classes have tight coupling with your DI container and cannot be used outside of it. Your classes cannot be instantiated (for example in unit tests) without reflection.

Which injection is not supported by Spring?

There are three types of injection: Constructor, Setter and Interface. Spring doesn't support the latest directly(as I have observed people saying).

Which is the best dependency injection in Spring?

Setter Injection is the preferred choice when a number of dependencies to be injected is a lot more than normal, if some of those arguments are optional than using a Builder design pattern is also a good option. In Summary, both Setter Injection and Constructor Injection have their own advantages and disadvantages.

What is the best method for dependency injection in Spring Framework?

Annotation of constructors for dependency injection has been optional since Spring Framework version 4.2. Constructor based dependency injection is certainly considered a best practice. There was a time I personally favored setter based injection, but have come around to constructor based.

What is inversion of control and dependency injection in spring?

The design principle of Inversion of Control emphasizes keeping the Java classes independent of each other and the container frees them from object creation and maintenance. These classes, managed by Spring, must adhere to the standard definition of Java-Bean. Dependency Injection in Spring also ensures loose-coupling between the classes.

How to use project Lombok for dependency injection in spring?

Now, the secret sauce using Project Lombok for best practices in dependency injection is to: Now, Project Lombok will generate a constructor for all properties declared final. And Spring will automatically use the Lombok provided constructor to autowire the clase. This is a real nice way of doing this. Your code stays very clean.

What is the best type of dependency injection in Java?

Constructor based dependency injection is certainly considered a best practice. There was a time I personally favored setter based injection, but have come around to constructor based.


Video Answer


1 Answers

The documentation says:

you can express the non-required nature of a particular dependency through Java 8’s java.util.Optional, as the following example shows:

public class SimpleMovieLister {

    @Autowired
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
        ...
    }
}

So using Optional as the type of a bean is not a good idea.

like image 149
JB Nizet Avatar answered Oct 17 '22 21:10

JB Nizet