Han*_*ank 5 java dependency-injection hk2
在使用由依赖注入框架(比如HK2)管理的服务时,使用方法链是否可以接受?
我不确定是否允许"缓存"实例,即使它仅在注入范围内.
示例服务创建披萨:
@Service
public class PizzaService {
private boolean peperoni = false;
private boolean cheese = false;
private boolean bacon = false;
public PizzaService withPeperoni() {
peperoni = true;
return this;
}
public PizzaService withCheese() {
cheese = true;
return this;
}
public PizzaService withBacon() {
bacon = true;
return this;
}
public Pizza bake() {
// create the instance and return it
}
}
Run Code Online (Sandbox Code Playgroud)
这里将服务注入JAX-RS资源:
@Path('pizza')
public class PizzaResource {
@Inject
PizzaService pizzaService;
@GET
public Response getPizza() {
Pizza pizza = pizzaService
.withPeperoni()
.withCheese()
.bake();
return Response.ok(pizza).build();
}
}
Run Code Online (Sandbox Code Playgroud)
基于@JinKwon 的答案及其评论,这是我的解决方案:
@PerLookup,因为@Singleton这是默认值。(感谢@M. Deinum)@RequestScoped默认的了。但其他代码(后台进程、单元测试等)可能具有不同的范围,并且Provider每次都会创建单独的新实例,从而产生差异。按照这种方法,我可以使用方法链接,返回this. 另外,这对我来说很重要,该实例由 DI 内核管理,并且可以访问依赖注入本身。
服务:
@Service
@PerLookup
public class PizzaService {
Pizza pizza = new Pizza(); // naked pizza by default
@Inject
OvenService oven; // just to show that I can use @Inject here
public PizzaService withPeperoni() {
pizza.peperoni = true;
return this;
}
public PizzaService withCheese() {
pizza.cheese = true;
return this;
}
public PizzaService withBacon() {
pizza.bacon = true;
return this;
}
public Pizza bake() {
return oven.bake(pizza);
}
}
Run Code Online (Sandbox Code Playgroud)
资源:
@Path('pizza')
public class PizzaResource {
@Inject
PizzaService pizzaService;
@GET
public Response getPizza() {
Pizza pizza = pizzaService
.withPeperoni()
.withCheese()
.bake();
return Response.ok(pizza).build();
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试(通过 a 注入的示例javax.inject.Provider):
@HK2
@Test
public class PizzaServiceNGTest {
@Inject
PizzaService pizzaService;
@Inject
Provider<PizzaService> pizzaServiceProvider;
public void testProviderInjection() {
Pizza pizza;
// pizza with the works
pizza = pizzaServiceProvider.get()
.withPeperoni()
.withBacon()
.withCheese()
.bake();
assertTrue(pizza.peperoni);
assertTrue(pizza.bacon);
assertTrue(pizza.cheese);
// naked pizza
pizza = pizzaServiceProvider.get()
.bake();
assertFalse(pizza.peperoni);
assertFalse(pizza.bacon);
assertFalse(pizza.cheese);
}
public void testDirectInjection() {
Pizza pizza;
// pizza with the works
pizza = pizzaService
.withPeperoni()
.withBacon()
.withCheese()
.bake();
assertTrue(pizza.peperoni);
assertTrue(pizza.bacon);
assertTrue(pizza.cheese);
// naked pizza
pizza = pizzaService
.bake();
// this is where it goes wrong: the pizzaService hasn't been reset and
// is messing up the order!
assertFalse(pizza.peperoni); // will fail
assertFalse(pizza.bacon); // will fail
assertFalse(pizza.cheese); // will fail
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |