Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring's Annotation Type Required deprecation

Spring's Annotation Type Required is marked as deprecated

Deprecated. as of 5.1, in favor of using constructor injection for required settings (or a custom InitializingBean implementation)

Same for relevant RequiredAnnotationBeanPostProcessor

But it's not clear what's the replacement, it seems that it should be unavailable.

Is this change prevent us marking method as required unless it's part of constructor method ? to prevent unexpected exceptions on class creation ?

like image 956
user7294900 Avatar asked Nov 18 '18 06:11

user7294900


People also ask

Is required annotation deprecated?

Yes , it is deprecated but still you can use it by mentioning below in xml file.

Why is annotation deprecated?

The @Deprecated annotation tells the compiler that a method, class, or field is deprecated and that it should generate a warning if someone tries to use it.

What is @required annotation?

Advertisements. The @Required annotation applies to bean property setter methods and it indicates that the affected bean property must be populated in XML configuration file at configuration time. Otherwise, the container throws a BeanInitializationException exception.

What is @value annotation in Spring?

Spring @Value annotation is used to assign default values to variables and method arguments. We can read spring environment variables as well as system variables using @Value annotation. Spring @Value annotation also supports SpEL.


1 Answers

There are three ways to inject a bean via annotation:

Field injection

@Autowired
private FooService fooService;

Setter injection

private FooService fooService;

@Autowired
public void setFooService(FooService fooService) {
    this.fooService = fooService
}

Constructor injection (this is the mentioned replacement)

private final FooService fooService;

@Autowired
public MyComponent(FooService fooService) {
    this.fooService = fooService;
}

As you can see, the only way to declare your Service final is by using the constructor injection, which replaces the @Required annotation because it forces the user of your class to instantiate it with the required services. The user does not have to be Spring, it could be a simple unit test as well.

You should use constructor injection for mandatory dependencies and setter injections for optional dependencies instead of field injection. Some reasons why:

  • It makes it clear to everybody which dependencies are required
  • It makes testing easier
  • You can make your objects immutable

Further reading:

  • http://olivergierke.de/2013/11/why-field-injection-is-evil/
  • https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/
  • https://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/

Update: non-annotated constructor injection

As one commentator was wondering about a final field annotated with @Autowired while the constructor was not annotated:

If a class only declares a single constructor to begin with, it will always be used, even if not annotated.

https://docs.spring.io/spring-framework/docs/5.2.5.RELEASE/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html ("Autowired Constructors")

But even though it is not necessary to annotate the constructor in this case, I would still do it: it documents the code and if anyone will ever add another (non-annotated) constructor, the code will still work.

like image 58
qutax Avatar answered Oct 12 '22 19:10

qutax