I've read that @Required uses to make sure the property has been set. But when I try to use it along with Spring Annotation Configuration it doesn't work.
Below you can familiarize with my code base.
@Configuration
@ComponentScan
public class AppConfig {
@Bean(initMethod = "initMethod")
public SimpleClass simpleClass(){
return new SimpleClass();
}
}
public class SimpleClass implements InitializingBean {
private int n;
public SimpleClass() {
System.out.println("constructor");
}
public int getN() {
return n;
}
@Required
public void setN(int n) {
System.out.println("setter");
this.n = n;
}
void initMethod(){
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet()");
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SimpleClass simpleClass = context.getBean(SimpleClass.class);
}
}
Why does Spring application context create the SimpleClass Bean and don't complain about the absence of injection via setter?
UPD: When I try to do the same using XML configuration and add then I receive a "Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Property 'n' is required for bean 'simple'"
@Required
documentation states (emphasis is mine) :
Marks a method (typically a JavaBean setter method) as being 'required': that is, the setter method must be configured to be dependency-injected with a value.
With Spring in order to configure a method as dependency injected you have to specify it (@Autowired
is the standard way).
But specifying both @Autowired
and @Required
on a method seems clumsy today :
@Autowired
@Required
public void setN(int n) {
System.out.println("setter");
this.n = n;
}
Instead, to configure the setter to be both dependency-injected and required I advise to use only @Autowired
that by default is required as you can notice :
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
So it is enough :
@Autowired
public void setN(int n) {
System.out.println("setter");
this.n = n;
}
As a side note, the setter injection will probably fail as the int n
will probably not be resolved as a dependency. The @Value
annotation on the parameter could probably help you.