æè¿ãç§ã¯
Guiceã
DIãã¬ãŒã ã¯ãŒã¯ãšããŠäœ¿çšããŠããããŒã ãšé »ç¹ã«äŒãå§ããŸããã ç§ã¯ãããæããŸããïŒæãã
æ¥ãéãããŸãïŒïŒïŒããããŠãããã¯ç§ã®äººçã§éåžžèµ·ããããã«ãç§ã®ææãå
·äœåããŸãã-ç§ã¯
Guiceãç©æ¥µçã«äœ¿çšããŠãããããžã§ã¯ãã«ä¹ããŸãã...
ããªãã®éã®åºçç©ïŒãã·ã¢èªã®åºçç©ãå«ãïŒããã§ã«ãã®ãã¬ãŒã ã¯ãŒã¯ã§ã€ã³ã¿ãŒãããã«èç©ãããŠããŸããããã¯æå ±ã§ãã ãããããããžã§ã¯ãã§ã¯ãæ¢æã®ãœãªã¥ãŒã·ã§ã³ãèŠã€ããããšãã§ããªãç¶æ³ã«çŽé¢ããŸããã
ãã®èšäºã§ã¯ã
Guiceãšãã®
æ¡åŒµæ©èœã®å®éã®äœ¿ç𿹿³ãå床瀺ããŸãïŒ
AssistedInject ã
MutiBinding ãããã³
Genericsã®äœ¿çš ã æåã«åé¡ã®æ¬è³ªã説æããæ¬¡ã«ãã®è§£æ±ºçãç¹°ãè¿ã説æããŸãã
ç§ã¯èªè
ã«ãã¬ãŒã ã¯ãŒã¯ãšäžè¬çãª
DIã«ã€ããŠã®åºæ¬çãªã¢ã€ãã¢ã®ååšãæå³ããã®ã§ãåºæ¬ãçç¥ããŸãã ããã«ãåªãã
ããã¥ã¡ã³ãããã
ãŸã ã
ãããžã§ã¯ãã®ãœãŒã¹ã³ãŒããšãã®å埩ã®å±¥æŽã¯
githubã§èŠã€ããããšãã§ããŸãã
1.ãªã¯ãšã¹ããã³ãã©ãŒ
ç¶æ³ã¯æ¬¡ã®ãšããã§ãã ãã®ãªã¯ãšã¹ãã®ãšã°ãŒãã¥ãŒã¿ãŒãäœæããããã«å¿
èŠãªãã©ã¡ãŒã¿ãŒãšããšã°ãŒãã¥ãŒã¿ãŒããã®åŸã®äœæ¥ã«äœ¿çšããåŒæ°ã䜿çšããŠããªã¯ãšã¹ããïŒäŸãã°
RESTãä»ããŠïŒå°çãããšæ³åããŠãã ããã
public class Request { public String parameter; public int argument; }
å€ãã®
ã¯ãŒã«ãŒãšã°ãŒã¯ãã£ãïŒéå±€å
šäœïŒãããããããããäœæ¥ãå®äºããããã«ãµãŒãã¹ã®åœ¢ã§äŸåé¢ä¿ãå¿
èŠãšããäŸåé¢ä¿ã®ã»ããã¯ãšã°ãŒãã¥ãŒã¿ãŒã«ãã£ãŠç°ãªãå ŽåããããŸãã ããããæœè±¡ã¯ã©ã¹ãš2ã€ã®åå«ããã®åçŽãªéå±€ã®äŸãšèããŠãã ããã å®éããã¡ãããããã¯ã©ã®
Nã§ãæ©èœããã¯ãã§ã
ããããã£ãŠã
Workerãããã¿ã€ãïŒ
public abstract class Worker{ protected final int argument; public Worker(int argument) { this.argument = argument; } public abstract void doWork(); }
ã¯ãŒã«ãŒå®è£
èªäœïŒ
public class Worker1 extends Worker { private ServiceA serviceA; private ServiceB serviceB; public Worker1(ServiceA serviceA, ServiceB serviceB, int argument) { super(argument); this.serviceA = serviceA; this.serviceB = serviceB; } @Override public void doWork() { System.out.println(String.format("Worker1 starts work with argument %d services %s and %s", argument, serviceA, serviceB)); } } public class Worker2 extends Worker { private ServiceB serviceB; private ServiceC serviceC; public Worker2(ServiceB serviceB, ServiceC serviceC, int argument) { super(argument); this.serviceB = serviceB; this.serviceC = serviceC; } @Override public void doWork() { System.out.println(String.format("Worker2 starts work with argument %d services %s and %s", argument, serviceB, serviceC)); } }
ã·ã³ãã«ãªãã³ãã©ãŒå®è£
ãã³ãã©ãŒã³ãŒããåããŠèŠããšãã¯ã次ã®ããã«ãªããŸããã
public class RequestHandler { private final ServiceA serviceA; private final ServiceB serviceB; private final ServiceC serviceC; public RequestHandler(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC) { this.serviceA = serviceA; this.serviceB = serviceB; this.serviceC = serviceC; } public void handleRequest(Request request) { Worker worker = null; if (request.parameter.equals("case1")) { worker = new Worker1(request.argument); } else if (request.parameter.equals("case2")) { worker = new Worker2(request.argument); }
ãªããã®ã¢ãããŒããæªãã®ã§ããïŒ ãã®ã³ãŒãã®çæã®çããªã¹ããäœæããããšããŸãã
- set *ã¡ãœãããä»ããäŸåé¢ä¿ã®æ³šå
¥ã¯ããã«å°è±¡çã§ãã ãããã®ã¡ãœãããæœè±¡ã¯ã©ã¹ã«è¿œå ããå¿
èŠããããŸããã
- ããã¯ã ServiceA ã ServiceB ãããã³ServiceCã® 3ã€ã®äŸåé¢ä¿ããã¹ãŠæœè±¡ã¯ã©ã¹ã«ç§»åããããšãæå³ããŸãã ãããã圌ã¯ãµãŒãã¹ã«ã€ããŠç¥ãå¿
èŠã¯ãããŸãããããã¯åœŒã®çžç¶äººã®ä»äºã§ãã ããšãã°ã Worker1ã¯çµ¶å¯Ÿã«ServiceCãå¿
èŠãšããŸããã
- if-else if -structureã Workeréå±€ã®çžç¶äººã®æ°ãå¢ãããšãéåžžã«æãããèŠããŸãã
- äŸåé¢ä¿ããã³ãã©ãŒã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŸãã ã¯ãšãªããã»ããµèªäœã¯ããããã®äŸåé¢ä¿ãèªèãã¹ãã§ã¯ãããŸãããã¯ãšãªããã»ããµã¯åœŒãå¿
èŠãšããŸããã ãããã¯ã ã¯ãŒã«ãŒã€ã³ã¹ã¿ã³ã¹èªäœã«ã®ã¿å¿
èŠã§ãã
- RequestHandlerã¯ã©ã¹ã«ã¯ãããŸãã«ãå€ãã®è²¬ä»»ããããŸããèŠæ±ãç®çã®Workerã«ãããã³ã°ããäœæããäŸåé¢ä¿ã眮ãããšãã§ããŸãã ïŒ SOLIDã®ååã«åŸã£ãŠïŒçæ³çã«ã¯ãã1ã€ã®ã¯ã©ã¹-1ã€ã®è²¬ä»»ããšãããã©ãã€ã ã«åŸããŸãã
ç§èªèº«ã¯ããã®ããã«ãŸãšããŸããã
ã¯ãŒã«ãŒã
Guiceã«è»¢éãããã®ã§ãïŒ
2. Guiceã®æ¥ç¶
ãŸãã
MavenäŸåé¢ä¿ã
pom.xmlã«è¿œå ããŸãã
<dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>${guice.version}</version> </dependency>
å·çæç¹ã§ã®
Guiceã®ææ°ããŒãžã§ã³ã¯4.2.0ã§ãã
ç¹°ãè¿ãç§»åããããšãçŽæããã®ã§ãæåã¯ã¿ã¹ã¯ãåçŽåããŸãã
Requestã«åŒæ°ã¯ãããŸããã
Workerã¯ããµãŒãã¹ã®åœ¢ã§ããã€ãã®äŸåé¢ä¿ãæã€éåžžã«åçŽãªã¯ã©ã¹ã§ãã ã€ãŸã æœè±¡ã¯ã©ã¹ã¯éåžžã«ç°¡åã§ãã
public abstract class Worker { public abstract void doWork(); }
ãããŠããã®å®è£
ã¯æ¬¡ã®ããã«ãªããŸãïŒ
Worker2ã®å®è£
ã¯äŒŒãŠããŸãïŒïŒ
public class Worker1 extends Worker{ private ServiceA serviceA; private ServiceB serviceB; @Inject public Worker1(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA; this.serviceB = serviceB; } @Override public void doWork() { System.out.println(String.format("Worker1 starts work with %s and %s", serviceA, serviceB)); } }
ãã®å Žåã®@
Injectã¢ãããŒã·ã§ã³ã¯ã
Workerã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã«ã¯ããã®ã¢ãããŒã·ã§ã³ã§ããŒã¯ãããã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããäœææã«ãã¹ãŠã®å
¥åãã©ã¡ãŒã¿ãŒãã³ã³ã¹ãã©ã¯ã¿ãŒã«æäŸããå¿
èŠãããããšããã¬ãŒã ã¯ãŒã¯ã«äŒããŸãã ãµãŒãã¹ãã©ãã§æã«å
¥ãããã¯æ°ã«ããªããããããŸãããã
Guiceããã¹ãŠãããŠãããŸãã
RequestHandlerã¯æ¬¡ã®ããã«ãªããŸãã
@Singleton public class RequestHandler { private Provider<Worker1> worker1Provider; private Provider<Worker2> worker2Provider; @Inject public RequestHandler(Provider<Worker1> worker1Provider, Provider<Worker2> worker2Provider) { this.worker1Provider = worker1Provider; this.worker2Provider = worker2Provider; } public void handleRequest(Request request) { Worker worker = null; if (request.parameter.equals("case1")) { worker = worker1Provider.get(); } else if (request.parameter.equals("case2")) { worker = worker2Provider.get(); } worker.doWork(); } }
ãã®ã¯ã©ã¹ã®ãµãŒãã¹ãžã®äŸåé¢ä¿ãåãé€ããããšãããã«ããããŸãã 代ããã«ã
Workerã«ãã£ãŠå
¥åããã
ãããã€ããŒã泚å
¥ãããŸããã ããã¥ã¡ã³ãããïŒ
ãããã€ããŒ<T>-ã¿ã€ãTã®ã€ã³ã¹ã¿ã³ã¹ãæäŸã§ãããªããžã§ã¯ã
ãã®å Žåã
ãããã€ããŒã¯
Guiceãã¬ãŒã ã¯ãŒã¯ã«ãã£ãŠæäŸããããã¡ã¯ããªãŒã§ãã
Workerã¯ã©ã¹ã«ãã£ãŠå
¥åããããããã€ããŒãžã®äŸåé¢ä¿ãååŸããåŸã
.get()
ã¡ãœãããåŒã³åºããã³ã«ã
Workerã¯ã©ã¹ã®æ°ããã€ã³ã¹ã¿ã³ã¹ãååŸããŸãïŒãã¡ããã
Workerã
SingletonãšããŠå®£èšãããŠããªãéãïŒã
RequestHandlerã¯ãé çªã«@
Singletonã¢ãããŒã·ã§ã³ã§ããŒã¯ãããŠããããšã«æ³šæããŠãã ããã ããã¯ã
Guiceãã¢ããªã±ãŒã·ã§ã³ã«ãã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã2
ã€ãªãããšã確èªããããšãæå³ããŸãã
ã³ãŒããå®è¡ããŸãã
public static void main( String[] args ) { Request request = new Request(); request.parameter = "case1"; request.argument = 5; Injector injector = Guice.createInjector(); RequestHandler requestHandler = injector.getInstance(RequestHandler.class); requestHandler.handleRequest(request); request.parameter = "case2"; requestHandler.handleRequest(request); }
å®è¡çµæWorker1ã¯ServiceAãšServiceBã§äœæ¥ãéå§ããŸã
Worker2ã¯ServiceBãšServiceCã§äœæ¥ãéå§ããŸã
3.åŒæ°ãæãã
ãããŠãå
ã®åœ¢åŒã®
Workerã¯ã©ã¹ã«æ»ããŸãã ãããè¡ãã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã«æ°ãã
åŒæ°ãã©ã¡ãŒã¿ãŒãæž¡ããŸãã
@Inject public Worker1(ServiceA serviceA, ServiceB serviceB, int argument) {
åé¡ã¯ãã¢ãããŒã·ã§ã³ãããå Žåã@
Inject Guiceãã³ã³ã¹ãã©ã¯ã¿ãŒã§æå®ããããã¹ãŠã®ãã©ã¡ãŒã¿ãŒãæäŸããããã
Runtimeã§åœ¢æããããã©ã¡ãŒã¿ãŒãæž¡ãã®ãé£ãããªãããšã§ãã
ãã¡ãããç¬èªã®
Factoryãäœæããããšã§ãã®åé¡ã解決ã§ããŸãã
åŽåè
å·¥å Ž @Singleton public class WorkerFactory { private ServiceA serviceA; private ServiceB serviceB; private ServiceC serviceC; @Inject public WorkerFactory(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC) { this.serviceA = serviceA; this.serviceB = serviceB; this.serviceC = serviceC; } public Worker1 createWorker1 (int argument) { return new Worker1(serviceA, serviceB, argument); } public Worker2 createWorker2 (int argument) { return new Worker2(serviceB, serviceC, argument); } }
äžèšã®ã³ãŒããæ£ç¢ºã«å®è¡ãããšãåãçµæã衚瀺ãããŸãã
ãã®ãããªãã¡ã¯ããªãŒã«ã¯ãéåžžã«å€ãã®å®åã³ãŒããå«ãŸããŠããŸããäœæãããã¯ã©ã¹ã§äœ¿çšããããã¹ãŠã®äŸåé¢ä¿ãæç€ºçã«æå®ããããããæ³šå
¥ãã
newæŒç®åã䜿çšããŠåŒã³åºããŠã³ã³ã¹ãã©ã¯ã¿ãŒã«æç€ºçã«æž¡ãå¿
èŠããããŸãã
Guiceã¯ããã®æ¡åŒµæ©èœã«ãã£ãŠãã®éçšãåé¿ããŸãã
Guice AssistedInject
æ¡åŒµæ©èœã
Guiceã®æ¡åŒµæ©èœã«æ¥ç¶ããŸãã
<dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-assistedinject</artifactId> <version>${guice.version}</version> </dependency>
ããã§ã倧ããª
WorkerFactoryã¯ã©ã¹ãäœæãã代ããã«ãåãååã®ã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸãã
public interface WorkerFactory { Worker1 createWorker1 (int argument); Worker2 createWorker2 (int argument); }
ã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ã¯èšè¿°ããŸãã
ãGuiceãè¡ããŸãã
Moduleã䜿çšããŠãããæ§æããŸãã
public class Module extends AbstractModule { @Override protected void configure() { install(new FactoryModuleBuilder().implement(Worker1.class, Worker1.class) .implement(Worker2.class, Worker2.class) .build(WorkerFactory.class)); } }
ã¢ãžã¥ãŒã«ã¯ã
Guiceãã«ããŒæ§æã®ã¯ã©ã¹ãšããŠèŠãããšãã§ããŸãã
Injectorã®äœææã«è€æ°ã®ã¢ãžã¥ãŒã«ãæ¥ç¶ããããšãã§ããŸãããŸããã¢ãžã¥ãŒã«ãã¢ãžã¥ãŒã«ã«æ¥ç¶ããããšãã§ããŸããããã«ãããæè»ã§ã«ã¹ã¿ãã€ãºå¯èœã§èªã¿ãããæ§æã·ã¹ãã ãäœæã§ããŸãã
ãã¡ã¯ããªãŒãäœæããããã«ã
FactoryModuleBuilderã䜿çšã
ãŸãã ã ããã¥ã¡ã³ãããïŒ
FactoryModuleBuilder-åŒã³åºãå
ã®åŒæ°ãšã€ã³ãžã§ã¯ã¿ãŒãæäŸããå€ãçµã¿åãããŠãªããžã§ã¯ããæ§ç¯ãããã¡ã¯ããªãŒãæäŸããŸãã
GuiceãæäŸãããªããžã§ã¯ããšã«ã¹ã¿ã ãã©ã¡ãŒã¿ãçµã¿åãããæ©äŒããããŸãã
ãã¡ã¯ããªãŒã®äœæãããã«è©³ããåæããŸãããïŒ
ã¯ãŒã«ãŒã³ã³ã¹ãã©ã¯ã¿ãŒã®ã©ã®ãã©ã¡ãŒã¿ãŒããã¡ã¯ããªãŒãä»ããŠããŒã«
ããã¯ãã ãã©ã®ãã©ã¡ãŒã¿ãŒããã£ã¢ãªã³ã°ãã¬ãŒã ã¯ãŒã¯ã«æ®ããããã«ã€ããŠã
Guiceã«äŒããããšãå¿ããªãã§ãã ããã @
Assistedã¢ãããŒã·ã§ã³ã䜿çšããŠãããè¡ããŸãã
@AssistedInject public Worker1(ServiceA serviceA, ServiceB serviceB, @Assisted int argument)
@
Assistedã¢ãããŒã·ã§ã³ã¯ãç§ãã¡èªèº«ããã¡ã¯ããªãŒãã
Guiceã«æäŸããåŒæ°ã®äžã«çœ®ãããŸãã ãŸããéåžžããã®å Žåãã³ã³ã¹ãã©ã¯ã¿ãŒã§@
AssistedInject㯠@
Injectã«çœ®ãæããããŸãã
RequestHandlerãæžãæããŠã
WorkerFactoryã«äŸåé¢ä¿ã
远å ããŸãã
@Singleton public class RequestHandler { private WorkerFactory workerFactory; @Inject public RequestHandler(WorkerFactory workerFactory) { this.workerFactory = workerFactory; } public void handleRequest(Request request) { Worker worker = null; if (request.parameter.equals("case1")) { worker = workerFactory.createWorker1(request.argument); } else if (request.parameter.equals("case2")) { worker = workerFactory.createWorker2(request.argument); } worker.doWork(); } }
æåŸã«ãã1ã€è§ŠããŸãããã³ã³ããã¹ããäžããããã«ã
Guiceã¯ã¢ãžã¥ãŒã«ã«ã€ããŠèª¿ã¹ãå¿
èŠããããŸãã ã¢ãžã¥ãŒã«ãæå®ããã ãã§ã
InjectorãååŸããããã«å€æŽã¯ãããŸããã
Injector injector = Guice.createInjector(new Module());
å®è¡çµæWorker1ã¯ãåŒæ°5ãµãŒãã¹ServiceAããã³ServiceBã§äœæ¥ãéå§ããŸã
Worker2ã¯ãåŒæ°5ãµãŒãã¹ServiceBããã³ServiceCã§äœæ¥ãéå§ããŸã
4.ãã¡ã¯ããªãŒã®ãã©ã¡ãŒã¿ãŒå
æ°ãã
WorkeråŸç¶ã衚瀺ããã
ãã³ã«ãããã
WorkerFactoryã€ã³ã¿ãŒãã§ãŒã¹ã«è¿œå ããããã
Moduleã«å ±åããå¿
èŠãããã®ã¯
æ¬åœã§ããïŒ
Workerã§
WorkerFactoryããã©ã¡ãŒã¿ãŒåããããšã§ãããåãé€ãããšããåæã«
Guiceããããã©ã®ããã«æ±ãããèŠã€ããŸãããã
public interface WorkerFactory<T extends Worker> { T createWorker (int argument); }
ããã§ã
Guiceãã¬ãŒã ã¯ãŒã¯ã«ã
ã¯ãŒã«ãŒããšã«1ã€ãã€ã2ã€ã®ç°ãªããã¡ã¯ããªã€ã³ã¹ã¿ã³ã¹ãäœæããå¿
èŠãããããšãäŒããå¿
èŠããããŸãã å·¥å Žãã¿ã€ãããæ¹æ³ã ãã§ããïŒ çµå±ã®ãšããã
Javaã¯ãã®ãããªæ§é ã®èšè¿°ãèš±å¯ããŸããïŒ
WorkerFactory <Worker1> .class public class Module extends AbstractModule{ @Override protected void configure() { install(new FactoryModuleBuilder().implement(Worker.class, Worker1.class) .build(new TypeLiteral<WorkerFactory<Worker1>>() {})); install(new FactoryModuleBuilder().implement(Worker.class, Worker2.class) .build(new TypeLiteral<WorkerFactory<Worker2>>() {})); } }
ä»åã¯ã
implementã¡ãœããã®åŒæ°ã§ããã®ã·ã°ããã£ã«å¿
èŠãªãã®ã瀺ãããšãã§ããŸã
ãWorkerã¯æœè±¡ã¯ã©ã¹ã芪ã
Worker1ãŸãã¯
Worker2ã¯ãã®åå«ã§ããã察å¿ãããã¡ã¯ããªã«ãã£ãŠäœæãããŸãã
TypeLiteralã¯ã©ã¹ã䜿çšããŠ
ãžã§ããªãã¯ã«é¢ããåé¡ã解決ããŸããã
Guiceã®ããã¥ã¡ã³ãããïŒ
TypeLiteral <T>-ãžã§ããªãã¯åTã衚ããŸããJavaã¯ãžã§ããªãã¯åã衚çŸããæ¹æ³ããŸã æäŸããŠããªãããããã®ã¯ã©ã¹ã¯
ãããã£ãŠã
Javaã«ã¯ãã©ã¡ãŒã¿ãŒåãããã¯ã©ã¹ã«é¢ãã
ç¥èããªãããã
Guiceã¯ç¬èªã®ã¯ã©ã¹ãäœæããŸããã
éåžžã
Class <T>åŒæ°ã®ä»£ããã«
TypeLiteral <T>ã䜿çšã§ããŸãããªãŒããŒããŒããããã¡ãœãããèŠãã ãã§ãã
TypeLiteralãäœæãããšãã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã
protectedãšããŠå®£èšã
ããŠããããã
{}ãå¿ããã«å
¥ããŠãã ããã
ãã¡ã¯ããªã®äŸåé¢ä¿ã
RequestHandlerã«æ¥ç¶ããæ¹æ³ãèŠãŠã¿ãŸãããïŒ
@Singleton public class RequestHandler { private WorkerFactory<Worker1> worker1Factory; private WorkerFactory<Worker2> worker2Factory; @Inject public RequestHandler(WorkerFactory<Worker1> worker1Factory, WorkerFactory<Worker2> worker2Factory) { this.worker1Factory = worker1Factory; this.worker2Factory = worker2Factory; } public void handleRequest(Request request) { Worker worker = null; if (request.parameter.equals("case1")) { worker = worker1Factory.createWorker(request.argument); } else if (request.parameter.equals("case2")) { worker = worker2Factory.createWorker(request.argument); } worker.doWork(); } }
5.ãã«ããã€ã³ãã£ã³ã°
ãã®ããã
WorkerFactoryã®ãã©ã¡ãŒã¿ãŒåã
è¡ã ããã¹ãŠã®ãã¡ã¯ããªãŒã«åäžã®ã€ã³ã¿ãŒãã§ã€ã¹ãæ®ããŸãã
ãWorkerã¯ã©ã¹ã®æ°ããåå«ã远å ãããšãã«å±éããå¿
èŠã¯ãããŸããã ãã ãã代ããã«ã
WorkerFactory<WorkerN> workerNFactory
æ¯å
WorkerFactory<WorkerN> workerNFactory
ãã¡ã¯ããªã«æ°ããäŸåé¢ä¿ã泚å
¥ããå¿
èŠããããŸãã æ¬¡ã«ã
multibindingsæ¡åŒµæ©èœã䜿çšããŠããããä¿®æ£ããŸãã ç¹ã«ã
MapBinderã䜿çšã
ãŸã ã
MapBinder-è€æ°ã®ããããšã³ããªãåå¥ã«ãã€ã³ãããåŸã§å®å
šãªããããšããŠæ¿å
¥ããããã®APIã
MapBinderã䜿çš
ãããšããã¹ãŠã®äŸåé¢ä¿ã1ã€ã®ãããã«ãŸãšããŠåéããäžåºŠã«æ³šå
¥ã§ã
ãŸã ã
multibiningsæ¡åŒµæ©èœããããžã§ã¯ãã«æ¥ç¶ããŸãã
<dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-multibindings</artifactId> <version>4.2.0</version> </dependency>
ãããŠããã«
ã¢ãžã¥ãŒã«ã远å ããŸã-ãã¹ãŠã®éæ³ã¯ãã®äžã§èµ·ãããŸãã ãŸãã
MapBinderãäœæã
ãŸã ã
MapBinder<String, WorkerFactory> binder = MapBinder.newMapBinder(binder(), String.class, WorkerFactory.class);
ç¹å¥ãªããšã¯ãããŸããããããã³ã°ã®çš®é¡ãæå®ããã ãã§ã
ãStringåã®ãã©ã¡ãŒã¿ãŒãç®çã®
WorkerFactoryãã¡ã¯ããªã«äžèŽãããŸãã ãããã³ã°èªäœãå®è£
ããããšã¯æ®ã£ãŠããŸãã
ãã®ããã
Guice㯠ãç§ãã¡ã®å©ããåããŠã
Workerã®å·¥å Žãæ¢ã«äœæããŸããã
new TypeLiteral<WorkerFactory<Worker1>>(){}
åŒæ°ãåããªããžã§ã¯ãã«ãããã³ã°ããŸãã ãããè¡ãã«ã¯ã
addBinding()
ããã³
to()
ã¡ãœããã䜿çšããŸãã
TypeLiteralãåãå
¥ããã¡ãœããã®ãªãŒããŒããŒãããŒãžã§ã³ãããããšã«æ³šæããŠãã ããã ãããã£ãŠãã¢ãžã¥ãŒã«ã¯å®å
šã«è¡šç€ºãããŸãã
public class Module extends AbstractModule{ @Override protected void configure() { install(new FactoryModuleBuilder().implement(Worker.class, Worker1.class) .build(new TypeLiteral<WorkerFactory<Worker1>>() {})); install(new FactoryModuleBuilder().implement(Worker.class, Worker2.class) .build(new TypeLiteral<WorkerFactory<Worker2>>() {})); MapBinder<String, WorkerFactory> binder = MapBinder.newMapBinder(binder(), String.class, WorkerFactory.class); binder.addBinding("case1").to(new TypeLiteral<WorkerFactory<Worker1>>(){}); binder.addBinding("case2").to(new TypeLiteral<WorkerFactory<Worker2>>(){}); } }
æãè峿·±ãããšã¯ãã¹ãŠæ¢ã«è¡ãããŠããŸã
ãRequestHandlerã§å¿
èŠãªãªããžã§ã¯ãã䜿çšããŠ
MapãååŸããã ãã§ãã
@Singleton public class RequestHandler { private Map<String, WorkerFactory> workerFactoryMap; @Inject public RequestHandler(Map<String, WorkerFactory> workerFactoryMap) { this.workerFactoryMap = workerFactoryMap; } public void handleRequest(Request request) { Worker worker = workerFactoryMap.get(request.parameter) .createWorker(request.argument); worker.doWork(); } }
ã芧ã®ãšãããäŸåé¢ä¿ã䜿çšããŠ@
Injectããããå®è¡ãã
get()
ã¡ãœããã§ç®çã®ãã¡ã¯ããªãŒãååŸããŸãã
ããã ãã§ãïŒ
RequestHandler㯠Workerã®äœæãšå®è¡ã®ã¿ãæ
åœãããã¹ãŠã®ãããã³ã°ã¯ã¢ãžã¥ãŒã«ã«è»¢éãããŸããã æ°ãã
åŽåè
çžç¶äººã®åºçŸã§ãä»ã®äœã倿Žããã«ãããã«ããã«é¢ããæ
å ±ã远å ããå¿
èŠããããŸãã
å°ãçµè«
äžè¬çã«ã
Guiceã¯ãã®ã·ã³ãã«ããšãä»ã§ã¯ãäœãããå€ããšèšãã®ããã¡ãã·ã§ããã«ã§ãããããç§ã
楜ããŸããŠãããŸããã å€ãã®å ŽåãåçŽãªã¢ããªã±ãŒã·ã§ã³ã§ã¯
ãæ§æããŸã£ãã
ã¹ãããããŠã@
Injectã¢ãããŒã·ã§ã³ã§å¯Ÿå¿ã§ããŸãã 詳现ã«ã€ããŠã¯
ãgithubã®
wikiãã芧ãã ããã