使用dropwizard(3)-加入DI-dagger2
前言
習(xí)慣了Spring全家桶,對spring的容器愛不釋手。使用dropwizard,看起來確實(shí)很輕,然而,真正使用的時(shí)候不得不面臨一個(gè)問題。我們不可能一個(gè)resource就能把所有的業(yè)務(wù)邏輯囊括!那么,必然就要有負(fù)責(zé)處理邏輯的代碼,有要提取的公共的代碼,要做面向接口開發(fā)等等。按照簡單的用法,Java Bean就自己new,只要通過Jersey提供的web能力發(fā)出去就好。這樣寫下來,到處都需要new,難以測試等等。目前我最care的是,每個(gè)request過來都要new一堆重復(fù)的對象,垃圾回收頻繁。寫個(gè)單例不就解決了?是的,當(dāng)然要想到單例,然后發(fā)現(xiàn)幾乎所有的類都是設(shè)計(jì)成單例的。然后,一堆單例的代碼寫的死。這就是樣板代碼。于是,想到提取工具類,算了,不如用Dagger好了。
什么是Dagger
Dagger是Java里開源的DI框架中最火的之一,主要用在Android領(lǐng)域,很多特性也多針對Android開發(fā)的。因?yàn)锳ndroid開發(fā)對省電,性能之類的要求比較高,因此拋棄了反射,直接在編譯級別生成工廠。詳細(xì)學(xué)習(xí)測試:Dagger2之helloworld原理探究
Demo Source
https://github.com/Ryan-Miao/l4dropwizard
structure
. ├── pom.xml ├── readme.md └── src└── main├── java│?? └── com│?? └── test│?? ├── HelloWorldApplication.java│?? ├── bundles│?? │?? └── ConnectivityBundle.java│?? ├── configuration│?? │?? ├── HelloWorldConfiguration.java│?? │?? └── modules│?? │?? ├── ConnectAndReadConfig.java│?? │?? └── GithubApiConfig.java│?? └── domain│?? ├── connect│?? │?? ├── FeignClientBuilder.java│?? │?? ├── GithubClient.java│?? │?? └── GithubConnector.java│?? ├── entiry│?? │?? ├── GithubUser.java│?? │?? └── Saying.java│?? ├── exception│?? │?? └── UpstreamException.java│?? ├── health│?? │?? └── TemplateHealthCheck.java│?? ├── ioc│?? │?? ├── component│?? │?? │?? └── GithubComponent.java│?? │?? └── module│?? │?? ├── ConfigurationModule.java│?? │?? ├── ConnectorModule.java│?? │?? └── ServiceModule.java│?? ├── resource│?? │?? ├── GithubResource.java│?? │?? └── HelloWorldResource.java│?? └── service│?? ├── IGithubService.java│?? └── impl│?? └── GithubService.java└── resources└── config└── dev.yml本文基于之前的dropwizard入門演進(jìn).
添加dagger依賴
在properties結(jié)點(diǎn)下新增
<dagger.verion>2.12</dagger.verion>在dependencies下新增
<dependency><groupId>com.google.dagger</groupId><artifactId>dagger</artifactId><version>${dagger.verion}</version> </dependency>在build.plugins下新增plugin
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>UTF-8</encoding><annotationProcessorPaths><path><groupId>com.google.dagger</groupId><artifactId>dagger-compiler</artifactId><version>${dagger.verion}</version></path></annotationProcessorPaths></configuration> </plugin>在IDEA設(shè)置中,找到Build>Compiler>Annotation Processors, 選擇Enable annotation processing.
創(chuàng)建一個(gè)Component
下面創(chuàng)建Component,用來包容Resource類,對外提供Resource類。新建com.test.domain.ioc.component.GithubComponent
package com.test.domain.ioc.component;import com.test.domain.ioc.module.ServiceModule; import com.test.domain.resource.GithubResource; import dagger.Component;import javax.inject.Singleton;/** * Created by Ryan Miao on 10/26/17. */ @Singleton @Component(modules = {ServiceModule.class}) public interface GithubComponent {GithubResource gitHubResource(); }顯然,這個(gè)GithubResource需要注入一個(gè)service,于是聲明一個(gè)ServiceModule, 創(chuàng)建com.test.domain.ioc.module.ServiceModule
package com.test.domain.ioc.module;import com.test.domain.service.IGithubService; import com.test.domain.service.impl.GithubService; import dagger.Module; import dagger.Provides;import javax.inject.Singleton;/** * Created by Ryan Miao on 10/26/17. */ @Module(includes = ConnectorModule.class) public class ServiceModule {@Singleton@Providespublic IGithubService githubService(GithubService service) {return service;} }ServiceModule用來提供service注入,service接著依賴connector層,新建com.test.domain.ioc.module.ConnectorModule
package com.test.domain.ioc.module;import com.test.domain.connect.FeignClientBuilder; import dagger.Module; import dagger.Provides;import javax.inject.Singleton;/** * Created by Ryan Miao on 10/26/17. */ @Module(includes = ConfigurationModule.class) public class ConnectorModule {@Provides@Singletonpublic FeignClientBuilder feignClientBuilder(){return new FeignClientBuilder();}}在connecttor層中,需要調(diào)用GlobalConfiguration的配置項(xiàng),所以,單獨(dú)把配置提出來,引入。新增com.test.domain.ioc.module.ConfigurationModule
package com.test.domain.ioc.module;import com.test.configuration.HelloWorldConfiguration; import dagger.Module; import dagger.Provides;import javax.inject.Singleton;/** * Created by Ryan Miao on 11/20/17. */ @Module public class ConfigurationModule {private final HelloWorldConfiguration configuration;public ConfigurationModule(HelloWorldConfiguration configuration) {this.configuration = configuration;}@Provides@Singletonpublic HelloWorldConfiguration helloWorldConfiguration(){return configuration;} }這是依賴的最底層,我們通過手動構(gòu)造函數(shù)的方式注入configuration,這樣可以在dropwizard啟動時(shí)生成module,并且得到configuration。
引入我們的Component
這時(shí)候,build一下,dagger就會自動生成我們的工廠。
mvn clean install然后,在IDEA里的maven plugin里,右鍵,reimport。防止IDEA不認(rèn)識dagger自動生成的類。dagger自動生成的類位于target/generated-sources/annotations. 點(diǎn)擊刷新按鈕,刷新下maven依賴。
然后,在com.test.HelloWorldApplication中,新增
private void registerResources(HelloWorldConfiguration configuration, Environment environment) {GithubComponent component = DaggerGithubComponent.builder().configurationModule(new ConfigurationModule(configuration)).build();environment.jersey().register(component.gitHubResource()); }DaggerGithubComponent要在maven install之后,dagger生成的。完整啟動類如下:
public class HelloWorldApplication extends Application<HelloWorldConfiguration> {public static void main(String[] args) throws Exception {new HelloWorldApplication().run(args);}@Overridepublic String getName() {return "hello-world";}@Overridepublic void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {bootstrap.addBundle(new ConnectivityBundle());}@Overridepublic void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {final HelloWorldResource resource = new HelloWorldResource(configuration.getTemplate(),configuration.getDefaultName());final TemplateHealthCheck healthCheck =new TemplateHealthCheck(configuration.getTemplate());environment.healthChecks().register("template", healthCheck);environment.jersey().register(resource);environment.jersey().register(healthCheck);registerResources(configuration, environment);}private void registerResources(HelloWorldConfiguration configuration, Environment environment) {GithubComponent component = DaggerGithubComponent.builder().configurationModule(new ConfigurationModule(configuration)).build();environment.jersey().register(component.gitHubResource());} }當(dāng)然,我們的Resource也要改成Inject模式
public class GithubResource {private IGithubService service;@Injectpublic GithubResource(IGithubService service) {this.service = service;}@GET@Timed@Path("/users/{username}")public GithubUser getUserProfile(@PathParam("username") final String username) {return service.getUserProfile(username);}}啟動,運(yùn)行。一切OK。以后就可以在需要注入的類的構(gòu)造器上聲明@Inject, 或者在module里@Provide,就可以實(shí)現(xiàn)構(gòu)造解耦。測試不要太方便.
唯有不斷學(xué)習(xí)方能改變! -- Ryan Miao
總結(jié)
以上是生活随笔為你收集整理的使用dropwizard(3)-加入DI-dagger2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 把控站外seo效果的几个操作点
- 下一篇: 自定义实现栈的功能