Micronaut 限制注射類型

2023-02-27 14:45 更新

默認(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
}
  1. @Bean(typed=..) 用于只允許注入接口引擎而不是具體類型

  2. 該類必須實(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)
    }
}
  1. 嘗試查找 V8Engine 拋出 NoSuchBeanException

  2. 同時查找Engine接口成功


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號