Spring 使用@Autowired
注入的介面有多個@Bean
類時,可以搭配@Qualifier
控制要注入哪個實例。
例如下面是DemoService
介面,目前有兩個實作Bean類分別為DemoServiceOneImpl
及DemoServiceTwoImpl
。
DemoService
package com.abc.demo.servce;
public interface DemoService {
public void doService();
}
在@Service
注釋宣告這個Bean的名稱,例如DemoServiceOneImpl
的Bean名稱為"one"
。
DemoServiceOneImpl
package com.abc.demo.servce;
import org.springframework.stereotype.Service;
@Service("one") // <-- bean name is "one"
public class DemoServiceOneImpl implements DemoService {
@Override
public void doService() {
System.out.println("This is one...");
}
}
而DemoServiceTwoImpl
的Bean名稱為"two"
。
DemoServiceTwoImpl
package com.abc.demo.servce;
import org.springframework.stereotype.Service;
@Service("two") // <-- bean name is "two"
public class DemoServiceTwoImpl implements DemoService {
@Override
public void doService() {
System.out.println("This is two...");
}
}
下面為使用@Autowired
注入DemoService
實例的DemoController
。由於DemoService
有兩個Bean,所以此時可加上@Qualifier
來決定要注入哪個Bean實例,例如下面注入的實例為DemoServiceOneImpl
。
package com.abc.demo.controller;
import com.abc.demo.servce.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Qualifier("one") // <-- 告訴Spring注入名稱為"one"的Bean,即DemoServiceOneImpl
@Autowired
private DemoService demoService;
@GetMapping("/")
public void demo() {
demoService.doService(); // 多型,所以實際上是呼叫DemoServiceOneImpl.doService()
}
}
若有多個Bean但沒用@Qualifier
指明注入的對象,例如把上面@Qualifier
移除,則Spring啟動時會出現下面錯誤。
***************************
APPLICATION FAILED TO START
***************************
Description:
Field demoService in com.abc.demo.controller.DemoController required a single bean, but 2 were found:
- one: defined in file [../workspace/demo/target/classes/com/abc/demo/servce/DemoServiceOneImpl.class]
- two: defined in file [../workspace/demo/target/classes/com/abc/demo/servce/DemoServiceTwoImpl.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Process finished with exit code 1
沒有留言:
張貼留言