前言
Spring框架最開始被我熟知就是AOP和IOC昵观,其中IOC在開發(fā)過程中更是被廣泛使用晾腔,如果切換到一個新的框架沒有了依賴注入和控制反轉(zhuǎn),那么可以說一夜回到解放前了啊犬。那么灼擂,Quarkus框架中有沒有對應(yīng)的功能呢?
當(dāng)然也有觉至,Quarkus基于CDI規(guī)范提供了依賴注入的相關(guān)功能剔应,本文將進(jìn)行簡單介紹。
CDI-Contexts and Dependency Injection
簡單介紹
CDI(Contexts and Dependency Injection)语御,即上下文依賴注入峻贮,是J2EE6發(fā)布的一個標(biāo)準(zhǔn)規(guī)范,用于對上下文依賴注入的標(biāo)準(zhǔn)規(guī)范化应闯,思想應(yīng)該是來源于Spring的IOC纤控,存在的年頭已經(jīng)挺久遠(yuǎn)。但是之前一直沒怎么關(guān)注這個規(guī)范孽锥,都是用Spring Framework打天下嚼黔。
以前以為只能在J2EE中使用,但是在寫這篇文章的時候惜辑,發(fā)現(xiàn)在J2SE8.0已經(jīng)可以使用CDI了唬涧,只需要明確引導(dǎo)CDI容器即可。
簡單使用示例(J2SE)
以下以在一個簡單的Java項(xiàng)目中使用weld實(shí)現(xiàn)依賴注入進(jìn)行簡單示例盛撑,依賴包如下:
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.1.0.Final</version>
</dependency>
- 首先碎节,編寫接口類和實(shí)現(xiàn)類;
HelloService.class
/**
* Created at 2019/5/18 by centychen<292462859@qq.com>
*/
public interface HelloService {
/**
* example method.
*
* @return
*/
String sayHello();
}
HelloServiceImpl.class
import cn.centychen.examples.j2se.cdi.service.HelloService;
import javax.enterprise.inject.Default;
/**
* Created at 2019/5/18 by centychen<292462859@qq.com>
*/
@Default
public class HelloServiceImpl implements HelloService {
/**
* Example method implement.
*
* @return
*/
@Override
public String sayHello() {
return "Hello,This is an example for CDI.";
}
}
- 其次抵卫,添加
beans.xml
定義文件狮荔,內(nèi)容如下:
實(shí)際上添加一個空白文件也可以正常運(yùn)行。
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
</beans>
- 最后介粘,編寫測試啟動類
import cn.centychen.examples.j2se.cdi.service.HelloService;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
/**
* Created at 2019/5/18 by centychen<292462859@qq.com>
*/
public class Application {
/**
* main method.
*
* @param args
*/
public static void main(String[] args) {
SeContainer container = SeContainerInitializer.newInstance().initialize();
HelloService helloService = container.select(HelloService.class).get();
System.out.println(helloService.sayHello());
}
}
- 運(yùn)行測試殖氏,輸入日志如下,HelloService的實(shí)現(xiàn)類已經(jīng)正確注入姻采。
objc[13831]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/bin/java (0x10d96e4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10e9934e0). One of the two will be used. Which one is undefined.
五月 18, 2019 12:37:36 下午 org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 3.1.0 (Final)
五月 18, 2019 12:37:36 下午 org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
五月 18, 2019 12:37:37 下午 org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent
INFO: WELD-ENV-002003: Weld SE container 3f7714f9-0cea-48a0-b217-1147420967e0 initialized
Hello,This is an example for CDI.
Weld SE container 3f7714f9-0cea-48a0-b217-1147420967e0 shut down by shutdown hook
Quarkus依賴注入
Quarkus的依賴注入管理使用的是io.quarkus:arc
雅采,實(shí)際上就是CDI的一種實(shí)現(xiàn)。以下上一篇文章示例進(jìn)行簡單改造,實(shí)現(xiàn)依賴注入婚瓜。
- 編寫業(yè)務(wù)接口HelloService及其實(shí)現(xiàn)類HelloServiceImpl宝鼓,參考代碼如下:
HelloService.class:
/**
* Created at 2019/5/18 by centychen<292462859@qq.com>
*/
public interface HelloService {
/**
* Say hello method.
*
* @param name
* @return
*/
String sayHello(String name);
}
HelloServiceImpl.class:
import cn.centychen.quarkus.example.service.HelloService;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Default;
/**
* Created at 2019/5/18 by centychen<292462859@qq.com>
*/
@ApplicationScoped //標(biāo)志Bean的作用域?yàn)橐粋€應(yīng)用一個實(shí)例。
@Default //默認(rèn)巴刻,接口多實(shí)現(xiàn)時必須
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return String.format("Hello,%s!", name);
}
}
- 改造GreetingResource類愚铡,增加依賴注入以及業(yè)務(wù)接口調(diào)用,參考如下:
import cn.centychen.quarkus.example.service.HelloService;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
/**
* @author: cent
* @email: chenzhao@viomi.com.cn
* @date: 2019/5/4.
* @description:
*/
@Path("/hello")
public class GreetingResource {
@Inject
private HelloService helloService;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{name}")
public CompletionStage<String> hello(@PathParam("name") String name) {
//使用異步響應(yīng)
return CompletableFuture.supplyAsync(() -> helloService.sayHello(name));
}
}
-
啟動應(yīng)用胡陪,訪問接口沥寥,返回如下,證明依賴注入已經(jīng)成功:
總結(jié)
Quarkus的上下文依賴注入使用的是CDI標(biāo)準(zhǔn)規(guī)范督弓,實(shí)現(xiàn)依賴注入可以避免從Spring框架切換到Quarkus框架的使用上的不習(xí)慣营曼,因?yàn)楸救诉€沒特別深入地使用Quarkus框架,特別是并沒有在真實(shí)生產(chǎn)環(huán)境中使用過Quarkus框架愚隧,所以說Quarkus Arc能否達(dá)到Spring IOC的高度蒂阱,還需要時間驗(yàn)證。