栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

AbstractBeanDefinition的autowireMode自动装配模式属性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AbstractBeanDefinition的autowireMode自动装配模式属性

在AbstractBeanDefinition中有一个属性是autowireMode,该属性表示自动装配模式

在Spring中,注入方式有两种

  1. 通过set方法
  2. 通过构造函数(如果有多个构造函数会选择参数多的构造方法)

手动装配注入:

  • @Resource: 默认是通过name来查找注入值,如果不存在就报错

  • @Autowired 通过类型查找(类型),然后再通过name

AutowireMode(自动装配模型):在spring中有四种模式分别是:

  1. AUTOWIRE_NO = 0:默认装配模式,目前非xml配置都是使用这种方式,需要使用手动装配注入

  2. AUTOWIRE_BY_NAME = 1: 通过set方法,并且set方法的名称需要和bean的name一致

  3. AUTOWIRE_BY_TYPE = 2: 通过set方法,并且再根据bean的类型,注入属性,是通过类型配置

  4. AUTOWIRE_ConSTRUCTOR = 3: 通过构造器注入

模式说明
no(默认)不采用自动装配autowire机制。Bean 引用必须由 ref 元素定义。对于较大的部署,不建议更改默认设置(也就是说,官方推荐使用autowire_no),因为明确指定协作者可以提供更好的控制和清晰度。 在某种程度上,它记录了系统的结构。
byName通过属性的名称自动装配(注入)
Spring会在容器中查找名称与bean属性名称一致的bean,并自动注入到bean属性中;当然bean的属性需要有setter方法。
例如:bean A有个属性master,master的setter方法就是setMaster,A设置了autowire=“byName”,那么Spring就会在容器中查找名为master的bean通过setMaster方法注入到A中。
byType通过类型自动装配(注入)
Spring会在容器中查找类(Class)与bean属性类一致的bean,并自动注入到bean属性中,如果容器中包含多个这个类型的bean,Spring将抛出异常。如果没有找到这个类型的bean,那么注入动作将不会执行。
constructor类似于byType,但是是通过构造函数的参数类型来匹配
假设bean A有构造函数A(B b, C c),那么Spring会在容器中查找类型为B和C的bean通过构造函数A(B b, C c)注入到A中。与byType一样,如果存在多个bean类型为B或者C,则会抛出异常。但时与byType不同的是,如果在容器中找不到匹配的类的bean,将抛出异常,因为Spring无法调用构造函数实例化这个bean。
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
public static final int AUTOWIRE_BY_NAME=AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE=AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
public static final int AUTOWIRE_CONSTRUCTOR=AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

在AbstractAutowireCapableBeanFactory#populateBean方法中,对AutowireMode的判断

            int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                if (resolvedAutowireMode == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }

                if (resolvedAutowireMode == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

代码如下:

@Component
public class ConsumerA {
    private ProviderA providerA;
    public void setProviderA(ProviderA a) {
        this.providerA = a;
    }
    public void providerShow() {
        System.out.println(providerA);
    }
}
@Component
public class ProviderA {}
// 配置类,组件扫描根路径
@Configuration
@ComponentScan("com.modules.test")
public class TestConfig {
}
@Component
public class TestBeanFactoryProcessor implements BeanFactoryPostProcessor {
    private static final String BEAN_NAME = "consumerA";
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        //获取ConsumerA类的Bean定义
        AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition(BEAN_NAME);
        //修改ConsumerA类的装配模式autowireMode,默认值为AUTOWIRE_NO,不进行自动装配
        beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
    }
}
public class ProcessorMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(TestConfig.class);
        ConsumerA consumer = context.getBean(ConsumerA.class);
        consumer.providerShow();
        System.err.println(context.getBean(ProviderA.class));
        context.close();
    }
}

在上面的代码中,我们没有在ConsumerA类中的ProvierA属性加@Autowired或者@Resource注解,但是我们在TestBeanFactoryProcessor中修改了ConsumerA的装配模式,因此ConsumerA中的ProviderA还是会注入进去的。

如果使用默认的AUTOWIRE_NO装配模式,则不会自动注入进去,需要使用@Autowired或者@Resource

参考AutowireMode的一些理解

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/270822.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号