SptingBoot的项目业务增强和测试

1.如果一个接口有两个实现类,并且都(@Component)都交给bean管理,当测试类从bean中获取(@AutoWired)这个接口对象时,会出现什么问题?
package com.py.pj.commom.cache;
public interface Cache {

}
package com.py.pj.commom.cache;

import org.springframework.stereotype.Component;

@Component
public class SoftCache implements Cache{

}
        
package com.py.pj.commom.cache;

import org.springframework.stereotype.Component;

@Component
public class WeakCache implements Cache{

}
package com.py.pj.commom.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.py.pj.commom.cache.Cache;


@Component
public class SearchService {

    private Cache cache;



    public SearchService(Cache cache) {
        this.cache = cache;
        
    }

    // 外界通过get获得spring容器注入的cache对象
    public Cache getCache() {
        return cache;
    }
}

测试类

@SpringBootTest
public class TestCache {
    
    @Autowired
    @Qualifier("softCache")
    private Cache cache;

    @Test
    void testCache() {
        System.out.println(cache);
    }
}

image.png

  • 出现类似错误的原因:名为Cache的bean对象在默认的singleton作用域中有两个值softCache、weakCache。不知道取哪一个造成的错误。
  • 有三种解决方案:
    需要用到@Autowired和@Qualifier,@Qualifier需和@Autowired配合使用。

(1)直接在SearchService类中@Autowired给Cache注入值,并使用@Quailfier()选择注入类型的属性,在这里我们可以选择softCache和weakCache其中一个。

       @Autowired
    @Qualifier("softCache")
    private Cache cache;

    public SearchService() {

    }

image.png
(2)第二种是借助set方法和无参构造,给Cache注入为weakCache的值

public SearchService() {
    }
    // set这种方无参构造函数配合使用
    @Autowired
    @Qualifier("weakCache")
    public void setCache(Cache cache) {
        this.cache = cache;
    }

image.png
(3)使用有参构造方法,把@Qualifier加在参数类型之前,并定义属性的类型。

    // 独立使用
//    @Autowired // 描述构造方法可省略
    public SearchService(@Qualifier("softCache")Cache cache) {
        this.cache = cache;
        System.out.println(this.cache);
    }

image.png


2.在上面使用到了@Autowired和@Qualifier,则它们的应用规则和作用是什么?
  • Autowired:用于描述类中的属性或者方法(比如上面出现的构造方法)。Spring框架在运行规定时候,如果有bean对象的方法或者属性使用@Autowired描述,则Spring框架会根据指定的规则为属性赋值(DI)。
  • 其基本规则是:首先要检测容器中是否有与属性或方法参数类型相匹配的对象,假如有并且只有一个则直接注入。其次,假如检测到有多个,还会按照@Autowired描述的属性或方法参数名查找是否有名字匹配的对象,有则直接注入,没有则抛出异常。最后,假如我们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还可以使用@Qualifier注解对其属性或参数进行描述(此注解必须配合@Autowired注解使用)。具体过程可参考图-18的设计进行自行尝试和实践。

流浪成疯
7 声望3 粉丝

学习