问题
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?
回答1:
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.
回答2:
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.
回答3:
That is what the spring documentation says though right? the default is NO. So, even if you do explicitly specify it it shouldnt have any impact. Also, when you do specify a bean, what you did mention of it being Autowire.No is correct. so it shouldnt have any impact.
回答4:
no
The traditional Spring default.
No automagical wiring. Bean references must be defined in the XML file via the <ref/>
element (or ref
attribute).
We recommend this in most cases as it makes documentation more explicit.
Note that this default mode also allows for annotation-driven autowiring, if activated.
no
refers to externally driven autowiring only, not affecting any autowiring demands that the bean class itself expresses
来源:https://stackoverflow.com/questions/21020187/in-spring-what-does-autowire-autowire-no-do