From this Spring documentation I know that when I use @Bean, the default is already equivalent to:
@Bean(autowire = Autowire.NO)
(Default) No autowiring. Bean references must be defined via a ref element. Changing the default setting is not recommended for larger deployments, because specifying collaborators explicitly gives greater control and clarity. To some extent, it documents the structure of a system.
I am just trying to understand what this means for me. If my system is 100% Java Config and has no XML configuration, then from what I can tell, when I use @Bean, the 'Autowire.no' has no impact whatsoever.
EDIT
By "no impact" I mean that other @Autowired references to this bean ARE autowired (in other Java Config classes). I suspect that is because with Java Config there is no explicit 'ref element' defined, so this (default) setting has no effect.
Example:
First Config:
package a.b.c;
@Configuration
public class AlphaConfig {
@Bean(autowire = Autowire.NO)
public AlphaBeanType alphaBean() {
return new AlphaBeanType();
}
}
Then in second config:
package d.e.f;
import a.b.c.AlphaBeanType;
@Configuration
public class AnotherConfig {
@Autowire
private AlphaBeanType alphaBeanType;
@Bean
. . .
}
What I see is that 'alphaBeanType' is always autowired in the second config class - which seems to be in conflict with the documentation - hence my question.
end edit
Of course, I can't quite tell from the documentation! Does anyone know for sure?
Setting Autowire.NO
does not mean that the bean cannot be injected in other beans via @Autowire
. @Autowire
works by default by type, and can also work by name using @Qualifier
.
So if your bean has the right type or name, it will get inject in other beans, that's normal.
Autowire.NO
means something like:
Don't inject the properties of THIS bean being declared with
@Bean
neither by type or by name. If the bean properties are not set in the@Bean
method code, leave them unfilled.
This a code example of how this works, let's define two beans:
public class MyBeanTwo {
public MyBeanTwo() {
System.out.println(">>> MY Bean 2 created!");
}
}
public class MyBean {
private MyBeanTwo myBeanTwo;
public MyBean() {
System.out.println(">>>MyBean created !!");
}
public void setMyBeanTwo(MyBeanTwo myBeanTwo) {
System.out.println(">>> Injecting MyBeanTwo INTO MyBeanOne !!!");
this.myBeanTwo = myBeanTwo;
}
}
And some configuration:
@Configuration
public class SimpleConfigOne {
@Bean
public MyBean createMyBean() {
return new MyBean();
}
@Bean
public MyBeanTwo createMyBeanTwo() {
return new MyBeanTwo();
}
}
With this configuration, the startup of this application gives this log:
>>>MyBean created !!
>>> MY Bean 2 created!
Meaning one instance of each bean was created, but MyBean
did NOT get injected with MyBeanTwo
, even tough a bean with the correct type existed.
By declaring MyBean
like this:
@Bean(autowire = Autowire.BY_TYPE)
public MyBean createMyBean() {
return new MyBean();
}
MyBeanOne
is now eligible to have it's properties set via autowiring by type.
The startup log becomes:
>>>MyBean created !!
>>> MY Bean 2 created!
>>> Injecting MyBeanTwo INTO MyBeanOne !!!
This shows that MyBean
had MyBeanTwo
injected by type via a by type injection.
Reason why Autowire.NO is the default:
Usually we don't want to autowire the properties of beans created with @Bean
. What we usually do is set the properties explicitly via code for readability, as a form of documentation and to make sure the property is set with the correct value.
The autowire
element of the @Bean
annotation (as well as the autowire
attribute of the bean
element in xml-based config) determines the autowiring status of the bean's own properties and has no relation to how a bean which is marked with the @Bean
annotation will be injected into other beans.
On the other hand the @Autowired
annotation explicitly
marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.
So in your case the @Bean
annotation declared on the alphaBean
method with the default Autowire.NO
mode disables automatic (that is implicit) injection of the properties (if any) of the AlphaBeanType
bean. While the @Autowired
annotation indicates that an AlphaBeanType
bean should be injected into AnotherConfig
configuration object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With