java已经支持依赖注入(DI) 主要是@Inject标记
import javax.inject.Inject;
import org.jvnet.hk2.annotations.Service;
@Service
public class S2 {
@Inject S1 s1;
@Inject IS s0;
public S2() {
System.out.println("S2 construct");
}
}
@Service
public class S1 {
public S1() {
System.out.println("S1 construct");
}
}
@Contract
interface IS{ }
@Service
class S implements IS{ }
java只是做了规范。具体使用还是要靠具体的实现,主要有spring,Guice,HK2
spring需要在xml中配置映射关系,或者用注解标识后,支持自动扫描。
HK2没有自动扫描,需要使用者自己组装映射关系,或者自动扫描。下面是自动扫描的过程。
1、找出所有标记Service和Constact 标注的类和接口
Reflections reflections = new Reflections("com.zte");
Set<Class<?>> serviceClasses = reflections.getTypesAnnotatedWith(org.jvnet.hk2.annotations.Service.class);
System.out.println(serviceClasses);
Set<Class<?>> contractClasses = reflections.getTypesAnnotatedWith(org.jvnet.hk2.annotations.Contract.class);
System.out.println(contractClasses);
2、进行DI注入
ServiceLocator locator = ServiceLocatorFactory.getInstance().create("dw-hk2");
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
DynamicConfiguration config = dcs.createDynamicConfiguration();
for(Class<?> serviceClass:serviceClasses){
Class<?> linkTo = serviceClass;
for (Class<?> contractClass : contractClasses) {
if(contractClass.isAssignableFrom(serviceClass) && contractClass.isInterface() ){
linkTo = contractClass;
break;
}
}
config.bind( BuilderHelper.link(serviceClass).to(linkTo).in(Singleton.class).build() );
}
config.commit();
3、服务类已经注入完毕,可以使用了。
非服务类如果需要调用一个服务,可以通过查找获取
ServiceLocator locator = ServiceLocatorFactory.getInstance().find("dw-hk2");
System.out.println( locator.getService(S2.class) );
System.out.println( locator.getService(S1.class) );