• Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】


    自动装配

    1、歧义性

    我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器中注册了,要怎么去区分对哪一个Bean进行注入呢?

    如下情况,若用@Autowired的方式按类型注入,IOC容器就不知道应该注入哪个了:

    <bean name="source1" class="pojo.Source">
        <property name="fruit" value="橙子"/>
        <property name="sugar" value="多糖"/>
        <property name="size" value="超大杯"/>
    </bean>
    <bean name="source2" class="pojo.Source">
        <property name="fruit" value="橙子"/>
        <property name="sugar" value="少糖"/>
        <property name="size" value="小杯"/>
    </bean>

    Spring对这种情况提供了2个注解进行解决:

    @Primary 注解

    定义:代表首要的,当 Spring IoC 检测到有多个相同类型的 Bean 资源的时候,会优先注入使用该注解的类。

    问题:该注解只是解决了首要的问题,但是并没有选择性的问题。

    @Qualifier 注解

    定义:此注解可以让Spring使用name的方式进行Bean的装配以及注入

    /* 包名和import */
    public class JuiceMaker {
        ......
        @Autowired
        @Qualifier("source1")//指定注入名称为 "source1" 的 Bean 资源
        public void setSource(Source source) {
            this.source = source;
        }
    }

    2、使用@Bean 装配 Bean

    基础用法

    定义:@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。

    用法:标识这个方法可以产生一个Bean并且交给Spring容器管理,告诉Spring可以在这个方法中拿到一个Bean。

    PS:添加的bean的id为方法名

    @Configuration
    public class AppConfig {
    
        @Bean//用@Bean注解配置Bean时,bean的ID默认为方法的名称
        public TransferService transferService() {
            return new TransferServiceImpl();
        }
    
    }

    上面的代码等同于

    <beans>
        <bean id="transferService" class="com.acme.TransferServiceImpl"/>
    </beans>

    bean的依赖

    @bean 也可以依赖其他任意数量的bean,如果TransferService 依赖 AccountRepository,我们可以通过方法参数实现这个依赖。

    @Configuration
    public class AppConfig {
    
        @Bean
        public TransferService transferService(AccountRepository accountRepository) {//PS:此方法的入参就是返回值所依赖的对象
            return new TransferServiceImpl(accountRepository);
        }
    
    }

    3、Bean的作用域

    可以通过 @Scope 注解或者 <bean> 元素中的 scope 属性来设置Bean的作用域

    4、Spring 表达式

    一个例子简单了解下: 

    package pojo;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    @Component("elBean")
    public class ElBean {
        // 通过 beanName 获取 bean,然后注入role这个对象
        @Value("#{role}")
        private Role role;
        
        // 获取 bean 的属性 id,并注入给id这个变量
        @Value("#{role.id}")
        private Long id;
        
        // 调用 bean 的 getNote 方法,并注入给note这个变量
        @Value("#{role.getNote().toString()}")
        private String note;
        /* getter and setter */
    }

    小结: 

    @Value("#{}") 表示SpEl表达式,通常用来获取bean的属性,或者调用bean的某个方法,或者常量注入

    PS:简要的说,就是通过@Value这个注解注入对象或者属性给相应的变量(简单的理解为赋值操作)。

     

    参考资料:

  • 相关阅读:
    【计算机视觉】关于OpenCV中GPU配置编译的相关事项
    【计算机视觉】关于OpenCV中GPU配置编译的相关事项
    【miscellaneous】如何利用硬盘号和CPU序列号为软件加密
    【miscellaneous】如何利用硬盘号和CPU序列号为软件加密
    【miscellaneous】软件加密方法
    【miscellaneous】软件加密方法
    【计算机视觉】双目测距(六)--三维重建及UI显示
    【计算机视觉】双目测距(六)--三维重建及UI显示
    【计算机视觉】双目测距(四)--罗德里格斯变换
    【计算机视觉】双目测距(四)--罗德里格斯变换
  • 原文地址:https://www.cnblogs.com/riches/p/11526413.html
Copyright © 2020-2023  润新知