Proszę o wyjaśnienie adnotacji @ products w CDI

Czytałem o adnotacji @ Produces w CDI, ale nie rozumiem jej użycia.

public class Resources {

// Expose an entity manager using the resource producer pattern
@SuppressWarnings("unused")
@PersistenceContext
@Produces
private EntityManager em;                                        // 

@Produces
Logger getLogger(InjectionPoint ip) {                            // 
    String category = ip.getMember()
                        .getDeclaringClass()
                        .getName();
    return Logger.getLogger(category);
}

@Produces
FacesContext getFacesContext() {                                 // 
    return FacesContext.getCurrentInstance();
}

}

Wzięte z: http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/guide/GreeterQuickstart/#GreeterQuickstart-

Skąd kontener wie, jak wywołać metodę producenta? Jeśli wstrzyknę EntityManager, w jaki sposób kontener wywoła @ produces EntityManager? A jak można nazwać metodę producenta getloggera?

Ja też nie widzę powodu aby przejść przez wszystkie kłopoty.

Author: Luiggi Mendoza, 2013-05-14

2 answers

Sekcja 3.3 specyfikacji CDI daje całkiem dobry przegląd wysokiego poziomu wykorzystania @Produces adnotacja:

Metoda producenta działa jako źródło przedmiotów, które mają być wstrzykiwane, gdzie:

* obiekty, które mają zostać wstrzyknięte, nie muszą być instancjami beans, lub
• konkretny typ wstrzykiwanych obiektów może się różnić w czasie wykonywania, lub
* obiekty wymagają niestandardowej inicjalizacji, która nie jest wykonywana przez bean konstruktor.

Załóżmy na przykład, że chcesz pomostować między komponentem zarządzanym Java EE, takim jak menedżer jednostek, a innymi komponentami CDI, możesz użyć adnotacji @Produces. Kolejną zaletą jest to, że unikasz powielania adnotacji @PersistenceContext w warstwie data domain.

class A {
    @PersistenceContext       // This is a JPA annotation
    @Produces                 // This is a CDI 'hook'
    private EntityManager em; 
}

class B {
   @Inject                    // Now we can inject an entity manager
   private EntityManager em;
}

Innym przydatnym zastosowaniem jest poruszanie się po bibliotekach, które nie mają przyjaznych dla CDI fasoli (na przykład, brak domyślnych konstruktorów):

class SomeTPLClass {
    public SomeTPLClass(String id) {
    }
}

class SomeTPLClassProducer {
    @Produces
    public SomeTPLClass getInstance() {
        return new SomeTPLClass("");
    }
}

Javadoc dla produkuje pokazuje również interesujący (ale dość rzadki przypadek) przypadek produkcji nazwanej kolekcji, która może być później wstrzykiwana do innych zarządzanych ziaren (bardzo fajne): {]}

public class Shop { 
    @Produces @ApplicationScoped 
    @Catalog @Named("catalog") 
    private List<Product> products = new LinkedList<Product>(8);

    //...
}

public class OrderProcessor {
    @Inject
    @Catalog
    private List<Product> products;
}

Kontener jest odpowiedzialny za przetwarzanie wszystkich metod i pól oznaczonych adnotacją @ Produces i zwykle robi to podczas wdrażania aplikacji. Przetworzone metody i pola będą następnie wykorzystywane jako część rozdzielczości punktu wtrysku dla managed beans, w razie potrzeby.

 62
Author: Perception,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 06:55:58

Przykład nie do końca mi pasował. Co dit praca była drobnym tweak:

@Alternative
class SomeTPLClass {
    public SomeTPLClass(String id) {
    }
}

class SomeTPLClassProducer {
    @Produces
    public SomeTPLClass getInstance() {
        return new SomeTPLClass("");
    }
}

Więc musiałem dodać @Alternative na mojej klasie, aby pozbyć się błędu, że są dwie opcje dla @Default .

 0
Author: Hans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 14:48:22