Spring 50例常见错误(二)

 文章整理来源:Spring编程常见错误50例_spring_spring编程_bean_AOP_SpringCloud_SpringWeb_测试_事务_Data-极客时间

案例4:同一父类,多个子类 Bean

        “ 同一父类,多个子类 Bean ” 或者 “ 同一接口,多个实现类 Bean ”

public interface DataService {
    void deleteStudent(int id);
}

@Repository
public class OracleDataService implements DataService{
    @Override
    public void deleteStudent(int id) {
        "delete student info maintained by oracle";
    }
}

@Repository
public class CassandraDataService implements DataService{
    @Override
    public void deleteStudent(int id) {
        "delete student info maintained by cassandra";
    }
}


@RestController
public class StudentController {
    @Autowired
    DataService dataService;

    @RequestMapping(path = "students/{id}", method = RequestMethod.DELETE)
    public void deleteStudent(@PathVariable("id") @Range(min = 1,max = 100) int id){
        dataService.deleteStudent(id);
    };
}

        解析:当一个 Bean 被构建时,有两个核心步骤,

                        1. 通过构造器反射构造这个 Bean ;

                        2. 填充这个 Bean 的属性

                                2.1 找出所有需要依赖注入的方法和字段 findAutowiringMetadata

                                2.2 根据依赖信息找出对应依赖并完成注入 inject

        在上述例子中,dataService 会找出两个依赖 cassandraDataService 和 OracleDataService,

        在有多个依赖的情况下(只有一个的情况下,就算名字无法精确匹配,也可按照类型进行成功匹配注入),deternineAutowireCandidate 方法会先根据 @Primary 决策,其次是 @Priority ,最后是根据 Bean 的名字 严格匹配 来决策,如果没有 @Primary 和 @Priority 决策成功,名字也无法精确匹配,则告知无法选出合适的 Bean 注入。

        解决:1.其中一个加入 @Primary 或 @Priority 注解; 2.精确 Bean 的名字 ; 3. 使用 @Qualifier 

案例5:显示引用 Bean 时首字母大小写问题

        继续上面的例子,有多个依赖时,可以使用 @Qualifer 进行精确匹配注入,在定义 Bean 未指定其名称,首字母大小写问题

// 正确 CassandraDataService 的默认 Bean 名称首字母小写
@Autowired()
@Qualifier("cassandraDataService")
DataService dataService;

// 错误 SQLiteDataService 的默认 Bean 名称首字母非小写
@Autowired
@Qualifier("sQLiteDataService")
DataService dataService;

// 正确
@Autowired
@Qualifier("SQLiteDataService")
DataService dataService;

        解析:Spring 在 Bean 默认命名方法 buildDefaultBeanName ,如果一个类名是以两个大写字母开头的,则首字母不变,其它情况下默认首字母变成小写

        解决:显示给 Bean 起名

案例6:引用内部类 Bean

        继续上述的例子,在 StudentController 中,定义一个 内部类 Bean,并在其他地方进行注入,报 找不到 对应 Bean 错误。

public class StudentController {
    @Repository
    public static class InnerClassDataService implements DataService{
        @Override
        public void deleteStudent(int id) {
          //空实现
        }
    }
    //省略其他非关键代码
 }


// 报错,找不到 innerClassDataService 对应的 Bean
@Autowired
@Qualifier("innerClassDataService")
DataService innerClassDataService;

        解析:在 Spring 中,此内部类 会以这样的名字出现 StudentController.InnerClassDataService,经过首字母的变化后,最终成为 studentController.InnerClassDataService

        解决: @Qualifer 内部类需带上外部类的名称

@Autowired
@Qualifier("studentController.InnerClassDataService")
DataService innerClassDataService;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值