Quarkus框架入門之二:依賴注入

前言

Spring框架最開始被我熟知就是AOP和IOC,其中IOC在開發過程當中更是被普遍使用,若是切換到一個新的框架沒有了依賴注入和控制反轉,那麼能夠說一晚上回到解放前了。那麼,Quarkus框架中有沒有對應的功能呢? 固然也有,Quarkus基於CDI規範提供了依賴注入的相關功能,本文將進行簡單介紹。html

CDI-Contexts and Dependency Injection

簡單介紹

CDI(Contexts and Dependency Injection),即上下文依賴注入,是J2EE6發佈的一個標準規範,用於對上下文依賴注入的標準規範化,思想應該是來源於Spring的IOC,存在的年頭已經挺久遠。可是以前一直沒怎麼關注這個規範,都是用Spring Framework打天下。 之前覺得只能在J2EE中使用,可是在寫這篇文章的時候,發如今J2SE8.0已經可使用CDI了,只須要明確引導CDI容器便可。java

簡單使用示例(J2SE)

如下以在一個簡單的Java項目中使用weld實現依賴注入進行簡單示例,依賴包以下:git

<dependency>
            <groupId>org.jboss.weld.se</groupId>
            <artifactId>weld-se-core</artifactId>
            <version>3.1.0.Final</version>
        </dependency>
  • 首先,編寫接口類和實現類;

HelloService.classbootstrap

/**
 * Created at 2019/5/18 by centychen<292462859@qq.com>
 */
public interface HelloService {
    /**
     * example method.
     *
     * @return
     */
    String sayHello();
}

HelloServiceImpl.classjava-ee

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定義文件,內容以下: 實際上添加一個空白文件也能夠正常運行。
<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());
    }
}
  • 運行測試,輸入日誌以下,HelloService的實現類已經正確注入。
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,實際上就是CDI的一種實現。如下上一篇文章示例進行簡單改造,實現依賴注入。框架

  • 編寫業務接口HelloService及其實現類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:ide

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 //標誌Bean的做用域爲一個應用一個實例。
@Default //默認,接口多實現時必須
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return String.format("Hello,%s!", name);
    }
}
  • 改造GreetingResource類,增長依賴注入以及業務接口調用,參考以下:
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) {
        //使用異步響應
        return CompletableFuture.supplyAsync(() -> helloService.sayHello(name));
    }
}
  • 啓動應用,訪問接口,返回以下,證實依賴注入已經成功: image.png

總結

Quarkus的上下文依賴注入使用的是CDI標準規範,實現依賴注入能夠避免從Spring框架切換到Quarkus框架的使用上的不習慣,由於本人還沒特別深刻地使用Quarkus框架,特別是並無在真實生產環境中使用過Quarkus框架,因此說Quarkus Arc可否達到Spring IOC的高度,還須要時間驗證。測試

示例源碼

參考文章

相關文章
相關標籤/搜索