In Spring, what does 'autowire = Autowire.NO' do?

依然范特西╮ 提交于 2020-05-27 06:24:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!