2016-08-13 2 views
1

Ich entwickle eine Bibliothek mit CDI. Das funktioniert gut. Aber wenn ich versuche, diese Bibliothek als ein eingeschlossenes Glas in einem Projekt zu verwenden, beschwert sich CDI, dass es keine Abhängigkeiten zu verwalteten Beans auflösen kann, die im übergeordneten Projekt definiert sind.Wie CDI verwaltete Bean aus Elternklassenpfad verwenden

MyProject - MyLib.jar - MyManagedBean

So MyLib eine Bohne mit einem Klischee @foo kommentierte injizieren muss. Dieses Stereotyp wird auf MyManagedBean angewendet.

@foo 
public class MyManagedBean { 
    //... 
} 

Ich habe beans.xml auch zu meinem übergeordneten Projekt hinzugefügt. Aber es ist, als gäbe es 2 verschiedene CDI Container und MyLib kann nicht auf MyProject zugreifen.

Irgendwelche Vorschläge?

+0

Was ist Ihr Bereitstellungsmodell? –

Antwort

0

Ich konnte mit der CDI-Erweiterung auf die übergeordnete Klassendatei zugreifen. Documentation und Reflexion.

Dies ist der Code, den ich verwenden:

public class ConfigExtension implements Extension { 

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) { 
    Reflections reflections = new Reflections(""); 
    Set<Class<?>> types = reflections.getTypesAnnotatedWith(Tester.class); 
    types.remove(info.scandi.fusion.cucumber.Tester.class); 
    types.addAll(reflections.getTypesAnnotatedWith(Driver.class)); 
    types.addAll(reflections.getTypesAnnotatedWith(Worker.class)); 

    types.forEach(type -> { 
     abd.addBean(new FusionBean((Class<T>) type, bm)); 
    }); 
} 

} 

public class FusionBean<T> implements Bean<T>, Serializable, PassivationCapable { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 
private InjectionTarget<T> it; 
private Class<T> bean; 
private BeanManager bm; 

public FusionBean(Class<T> workerClass, BeanManager bm) { 
    this.bm = bm; 
    bean = workerClass; 
    AnnotatedType<T> at = bm.createAnnotatedType(bean); 
    // use this to instantiate the class and inject dependencies 
    it = bm.createInjectionTarget(at); 
} 

@Override 
public T create(CreationalContext<T> creationalContext) { 
    T instance = it.produce(creationalContext); 
    it.inject(instance, creationalContext); 
    it.postConstruct(instance); 
    return instance; 
} 

@Override 
public void destroy(T instance, CreationalContext<T> creationalContext) { 
    it.preDestroy(instance); 
    it.dispose(instance); 
    creationalContext.release(); 
} 

@Override 
public Set<Type> getTypes() { 
    Set<Type> types = new HashSet<>(); 
    //Use Apache Common Lang to get all Interfaces and Superclasses 
    types.addAll(ClassUtils.getAllInterfaces(bean)); 
    types.addAll(ClassUtils.getAllSuperclasses(bean)); 
    return types; 
} 

@Override 
public Set<Annotation> getQualifiers() { 
    Set<Annotation> annotations = new HashSet<>(); 
    for (int i = 0; i < bean.getAnnotations().length; i++) { 
     Class<? extends Annotation> possibleQualifier = bean.getAnnotations()[i].annotationType(); 
     if (bm.isQualifier(possibleQualifier)) { 
      annotations.add(bean.getAnnotations()[i]); 
     } 
    } 
    return annotations; 
} 

@Override 
public Class<? extends Annotation> getScope() { 
    for (int i = 0; i < bean.getAnnotations().length; i++) { 
     Class<? extends Annotation> possibleScope = bean.getAnnotations()[i].annotationType(); 
     if (bm.isStereotype(possibleScope)) { 
      for (Annotation annotation : possibleScope.getAnnotations()) { 
       if (bm.isScope(annotation.annotationType())) { 
        return annotation.annotationType(); 
       } 
      } 
     } 
    } 
    return null; 
} 

@Override 
public String getName() { 
    return bean.getName(); 
} 

@Override 
public Set<Class<? extends Annotation>> getStereotypes() { 
    Set<Class<? extends Annotation>> stereotypes = new HashSet<>(); 
    for (int i = 0; i < bean.getAnnotations().length; i++) { 
     Class<? extends Annotation> possibleStereotype = bean.getAnnotations()[i].annotationType(); 
     if (bm.isStereotype(possibleStereotype)) { 
      stereotypes.add(possibleStereotype); 
     } 
    } 
    return stereotypes; 
} 

@Override 
public boolean isAlternative() { 
    for (int i = 0; i < bean.getAnnotations().length; i++) { 
     if (bean.getAnnotations()[i].equals(Alternative.class)) { 
      return true; 
     } 
    } 
    return false; 
} 

@Override 
public Class<?> getBeanClass() { 
    return bean.getClass(); 
} 

@Override 
public Set<InjectionPoint> getInjectionPoints() { 
    return it.getInjectionPoints(); 
} 

@Override 
public boolean isNullable() { 
    return false; 
} 

@Override 
public String getId() { 
    return UUID.randomUUID().toString(); 
} 

} 

Der Trick ist, CDI Erweiterung Zugriff auf Eltern Classpath hat. Hier verwende ich die Reflection API, um Tester-, Driver- und Worker-Klassen zu erhalten, die der Benutzer, der mein Framework verwendet, angeben kann.

Verwandte Themen