使用dropwizard(3)-加入DI-dagger2


前言
习惯了Spring全家桶,对spring的容器爱不释手。使用dropwizard,看起来确实很轻,然而,真正使用的时候不得不面临一个问题。我们不可能一个resource就能把所有的业务逻辑囊括!那么,必然就要有负责处理逻辑的代码,有要提取的公共的代码,要做面向接口开发等等。按照简单的用法,Java Bean就自己new,只要通过Jersey提供的web能力发出去就好。这样写下来,到处都需要new,难以测试等等。目前我最care的是,每个request过来都要new一堆重复的对象,垃圾回收频繁。写个单例不就解决了?是的,当然要想到单例,然后发现几乎所有的类都是设计成单例的。然后,一堆单例的代码写的死。这就是样板代码。于是,想到提取工具类,算了,不如用Dagger好了。
什么是Dagger
Dagger是Java里开源的DI框架中最火的之一,主要用在Android领域,很多特性也多针对Android开发的。因为Android开发对省电,性能之类的要求比较高,因此抛弃了反射,直接在编译级别生成工厂。详细学习测试: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入门演进.
添加dagger依赖
在properties结点下新增
<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设置中,找到Build>Compiler>Annotation Processors, 选择Enable annotation processing.
创建一个Component
下面创建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();
}
显然,这个GithubResource需要注入一个service,于是声明一个ServiceModule, 创建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
@Provides
public 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
@Singleton
public FeignClientBuilder feignClientBuilder(){
return new FeignClientBuilder();
}
}
在connecttor层中,需要调用GlobalConfiguration的配置项,所以,单独把配置提出来,引入。新增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
@Singleton
public HelloWorldConfiguration helloWorldConfiguration(){
return configuration;
}
}
这是依赖的最底层,我们通过手动构造函数的方式注入configuration,这样可以在dropwizard启动时生成module,并且得到configuration。
引入我们的Component
这时候,build一下,dagger就会自动生成我们的工厂。
mvn clean install
然后,在IDEA里的maven plugin里,右键,reimport。防止IDEA不认识dagger自动生成的类。dagger自动生成的类位于target/generated-sources/annotations. 点击刷新按钮,刷新下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);
}
@Override
public String getName() {
return "hello-world";
}
@Override
public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
bootstrap.addBundle(new ConnectivityBundle());
}
@Override
public 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());
}
}
当然,我们的Resource也要改成Inject模式
public class GithubResource {
private IGithubService service;
@Inject
public GithubResource(IGithubService service) {
this.service = service;
}
@GET
@Timed
@Path("/users/{username}")
public GithubUser getUserProfile(@PathParam("username") final String username) {
return service.getUserProfile(username);
}
}
启动,运行。一切OK。以后就可以在需要注入的类的构造器上声明@Inject, 或者在module里@Provide,就可以实现构造解耦。测试不要太方便.
使用dropwizard(3)-加入DI-dagger2的更多相关文章
- Using Dagger2 in Android
Dagger2是一个Java和Android的依赖注入框架. 本文介绍Android中dagger2的基本使用. 其中包括@Inject, @Component, @Module和@Provides注 ...
- 使用dropwizard(6)-国际化-easy-i18n
前言 Dropwizard官方文档并没有提供国际化的模块,所以只能自己加.Spring的MessageResource用的很顺手,所以copy过来. Easy i18n 在整合Dropwizard的时 ...
- java DI 框架spring(web)、Guice(web)、Dagger&Dagger2(android)
java DI 框架spring(web).Guice(web).Dagger&Dagger2(android) (待续...)
- Dagger2 入门解析
前言 在为dropwizard选择DI框架的时候考虑了很久.Guice比较成熟,Dagger2主要用于Android.虽然都是google维护的,但Dagger2远比guice更新的频率高.再一个是, ...
- Dagger2 使用初步
Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagger1 由Square公司开发.依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性.Dagger 这个库的取名不 ...
- Dagger2 生成代码学习
接上一篇文章介绍了Dagger2的初步使用,相信刚接触的人会觉得很奇怪,怎么会有很多自己没有定义的代码出现,为什么Component的创建方式是那样的.为了搞清楚这些东西,我们需要查看一下Dagger ...
- 【Android - 框架】之Dagger2+MVP的用法
MVP模式本身相比于MVC模式就已经把View层和Controller层从Activity中进行了分离,将Model层和View层用Presenter层隔开,实现了初步的解耦.如果再加入Dagger2 ...
- Dagger2学习笔记
Dagger2是第一个使用生成代码的方式实现依赖注入的框架.作为Dagger的升级版本,自然有它的优势,优先注重的是执行效率.本文着重介绍Dagger2.官方据点传送门: https://google ...
- Android -- 带你从源码角度领悟Dagger2入门到放弃(三)
1, 前面两篇文章我们知道了怎么使用常用的四种标签,现在我们结合我们自己的项目中去简单的使用 在我们搭建项目的时候,一般会创建自己的Application,在里面进行一些初始化如一些第三方的Green ...
随机推荐
- python codis集群客户端(二) - 基于zookeeper对实例创建与摘除
在这一篇中我们实现了不通过zk来编写codis集群proxys的api,http://www.cnblogs.com/kangoroo/p/7481567.html 如果codis集群暴露zk给你的话 ...
- Qt+VS2015应用程序发布
本文以Qt 5.9.1+VS2015编译环境为例介绍应用程序发布流程,也适用于Qt+mingw的情况. 1. Qt依赖库 将需要发布的exe(如test.exe),放到单独的目录. 在"开始 ...
- jquery各种事件使用方法总结(from:天宇之游)
ps:本博客转自博主 天宇之游 ,地址:http://www.cnblogs.com/cwp-bg/ ,再次感谢天宇之游.jquery事件使用方法总结 一.鼠标事件1. click():鼠标单击事 ...
- MySQL中变量的总结
本文对MySQL中局部变量.用户变量.系统变量的理解进行总结. 一.局部变量 局部变量由DECLARE语句声明: DECLARE var_name[,...] type [DEFAULT value] ...
- IDEA搭建SpringMVC+Mybatis+Mysql+Maven框架
相关环境 Intellij IDEA Ultimate Tomcat JDK MySql 5.6(win32/win64) Maven (可使用Intellij IDEA自带的) 搭建步骤 创建项目工 ...
- 前端(各种demo):右侧导航栏的折叠和打开(不使用js)基础版和升级版
1.给div设置定位. 复习一下—— css中position有五种属性: static:默认值,没有定位 absolute:绝对定位,相对于父级元素进行定位 relative:相对定位 fixed: ...
- Java IO(Properties/对象序列化/打印流/commons-io)
Java IO(Properties/对象序列化/打印流/commons-io) Properties Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载. ...
- 脱壳第一讲,手工脱壳ASPack2.12的壳.ESP定律
脱壳第一讲,手工脱壳ASPack2.12的壳.ESP定律 一丶什么是ESP定律 首先我们要明白什么是壳.壳的作用就是加密PE的. 而ESP定律就是壳在加密之前,肯定会保存所有寄存器环境,而出来的时候, ...
- .NET之父 - Anders Hejlsberg
简介 安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi和.NET之父! 安德斯·海尔斯伯格曾在丹麦技术大学学习工 ...
- IOC杂谈(一)初识IOC
初衷 发现学习东西不单只是看,用,还有很重要一点就是记录,不然过个几个月再用到相同的知识时,你会发现你已经丢得差不多了,故此开始在博客园记录的同时也与各位同行分享知识. 正题 关于IOC,在刚工作时就 ...