默認(rèn)情況下,當(dāng)您使用 @Singleton 等范圍注釋 bean 時,bean 類及其實(shí)現(xiàn)的所有接口和它擴(kuò)展的超類都可以通過 @Inject 注入。
考慮上一節(jié)中有關(guān)定義 bean 的以下示例:
Java |
Groovy |
Kotlin |
@Singleton
public class V8Engine implements Engine { // (3)
@Override
public String start() {
return "Starting V8";
}
@Override
public int getCylinders() {
return 8;
}
}
|
@Singleton
class V8Engine implements Engine { // (3)
int cylinders = 8
@Override
String start() {
"Starting V8"
}
}
|
@Singleton
class V8Engine : Engine {
override var cylinders: Int = 8
override fun start(): String {
return "Starting V8"
}
}
|
在上述情況下,應(yīng)用程序中的其他類可以選擇注入接口 Engine 或具體實(shí)現(xiàn) V8Engine。
如果這是不可取的,您可以使用 @Bean 注釋的類型化成員來限制公開的類型。例如:
Java |
Groovy |
Kotlin |
@Singleton
@Bean(typed = Engine.class) // (1)
public class V8Engine implements Engine { // (2)
@Override
public String start() {
return "Starting V8";
}
@Override
public int getCylinders() {
return 8;
}
}
|
@Singleton
@Bean(typed = Engine) // (1)
class V8Engine implements Engine { // (2)
@Override
String start() { "Starting V8" }
@Override
int getCylinders() { 8 }
}
|
@Singleton
@Bean(typed = [Engine::class]) // (1)
class V8Engine : Engine { // (2)
override fun start(): String {
return "Starting V8"
}
override val cylinders: Int = 8
}
|
@Bean(typed=..) 用于只允許注入接口引擎而不是具體類型
該類必須實(shí)現(xiàn)typed定義的類或接口,否則會出現(xiàn)編譯錯誤
以下測試演示了使用編程查找和 BeanContext API 進(jìn)行類型化的行為:
Java |
Groovy |
Kotlin |
@MicronautTest
public class EngineSpec {
@Inject
BeanContext beanContext;
@Test
public void testEngine() {
assertThrows(NoSuchBeanException.class, () ->
beanContext.getBean(V8Engine.class) // (1)
);
final Engine engine = beanContext.getBean(Engine.class); // (2)
assertTrue(engine instanceof V8Engine);
}
}
|
class EngineSpec extends Specification {
@Shared @AutoCleanup
ApplicationContext beanContext = ApplicationContext.run()
void 'test engine'() {
when:'the class is looked up'
beanContext.getBean(V8Engine) // (1)
then:'a no such bean exception is thrown'
thrown(NoSuchBeanException)
and:'it is possible to lookup by the typed interface'
beanContext.getBean(Engine) instanceof V8Engine // (2)
}
}
|
@MicronautTest
class EngineSpec {
@Inject
lateinit var beanContext: BeanContext
@Test
fun testEngine() {
assertThrows(NoSuchBeanException::class.java) {
beanContext.getBean(V8Engine::class.java) // (1)
}
val engine = beanContext.getBean(Engine::class.java) // (2)
assertTrue(engine is V8Engine)
}
}
|
嘗試查找 V8Engine 拋出 NoSuchBeanException
同時查找Engine接口成功
更多建議: