Ich habe eine Suggestion, die mein Problem hier gelöst hat, habe ich vorgeschlagene Lösung versucht und nicht hier gearbeitet. In meiner Lösung muss jede Klasse mit @MyInjectable Annotation kommentiert werden.
1-Eine Annotation
@Retention(RUNTIME)
@Target(ElementType.TYPE)
public @interface MyInjectable {
}
2-erstellen AbstractBinder Implementierung
public class MyApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bindFactory(EMFFactory.class).to(EntityManagerFactory.class).in(Singleton.class);
bindFactory(EMFactory.class).to(EntityManager.class).in(RequestScoped.class);
bind(Environment.class).to(Environment.class);
scanAndBind("com.yourpackage.here");
}
private void scanAndBind(String packageName) {
try {
Class[] classes = getClasses(packageName);
for (Class<?> klazz:
classes) {
MyInjectable annotation = klazz.getAnnotation(MyInjectable.class);
if (annotation!= null) {
bind(klazz).to(klazz);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static Class[] getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes.toArray(new Class[classes.size()]);
}
private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
}
3-erstellen ResourceConfig
public class MyApplication extends ResourceConfig {
@Inject
public MyApplication(ServiceLocator locator) {
ServiceLocatorUtilities.enableImmediateScope(locator);
....
register(new MyApplicationBinder());
}
}
4-Configure richtig in web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>br.com.solutiontrue.ws</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>your.package.name.MyApplication</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.resource.validation.disable</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
@ jwells131313 - Ich bin sehr neugierig, warum eine solche Einrichtung nicht in HK2 enthalten war. –
Es ist, Sie haben es gerade benutzt! Aber ich denke, du meinst etwas, was das generisch mit jeder Klasse tun würde, die zufällig auftaucht (beachte, dass deine Lösung nur Klassen behandelt, die mit com.fastmodel beginnen). Die Sache ist, wie Sie sehen können, ist es trivial hinzuzufügen. Es ist vielleicht keine schlechte Idee, eine Version von diesem zu haben, die einfach ANY-Klasse hinzufügt, die injiziert werden muss, aber sie müsste mit Vorsicht verwendet werden, da es einige Klassen geben kann, die NICHT auf diese Art hinzugefügt werden sollen. Trotzdem ist es keine schlechte Idee für eine "Extras" -Funktion. – jwells131313