關於@Resource註解使用的注意事項

@Resource是Java自帶的@interface類型,類似於Spring的@Autowired。但是兩者的注入方式有很大的區別。@Resource是通過name注入,@Autowired是通過type注入,這也是這次刨坑的主要原因。

場景還原

背景介紹
  • 一個類SettingService加了@Service,name爲settingService(spring掃描自動命名機制-將類的首字母小寫當做name)
  • 另一個類BallGameSettingService也加了@Service,name爲ballGameSettingService

代碼如下:

@Service
public class SettingService {

    ......
}

@Service
public class BallGameSettingService{

    .......
}
導火線

以下注入將會出現異常:Error creating bean with name ‘ballGameSettingController’: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named ‘settingService’ is expected to be of type ‘com.xxx.BallGameSettingService’ but was actually of type ‘com.xxx.SettingService…EnhancerBySpringCGLIB..e4ce4a19’

public class BallGameSettingController extends BaseController {

    @Resource
    private BallGameSettingService settingService;

    ......
}

將上面的代碼換成以下三種寫法都可以:

public class BallGameSettingController extends BaseController {

    @Resource(name = "ballGameSettingService")
    private BallGameSettingService settingService;

    ......
}

或者

public class BallGameSettingController extends BaseController {

    @Resource
    private BallGameSettingService ballGameSettingService;

    ......
}

或者

public class BallGameSettingController extends BaseController {

    @Autowired
    private BallGameSettingService settingService;

    ......
}
根本原因:@Resource是通過name注入,@Autowired是通過type注入

在使用@Resource時,如果沒有設置name,也就是 @Resource(name = “ballGameSettingService”) 時,會默認取變量名稱當做name。所以造成這次異常的原因:

  • 我們環境中存在兩個@Service的bean,名字分別爲:settingService和ballGameSettingService,我們在通過以下代碼注入的時候,獲取到的是settingService(類型:SettingService),導致了類型出錯。
@Resource
private BallGameSettingService settingService;
  • 以下兩種正確寫法的本質是一樣,就是獲取ballGameSettingService(類型:BallGameSettingService)
public class BallGameSettingController extends BaseController {

    @Resource(name = "ballGameSettingService")
    private BallGameSettingService settingService;

    ......
}

public class BallGameSettingController extends BaseController {

    @Resource
    private BallGameSettingService ballGameSettingService;

    ......
}
  • 使用@Autowired的本質是通過BallGameSettingService類型去獲取
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章