úterý 3. října 2006

Anotační peklo?

Nevím jestli již aktivně používáte nebo jste alespoň viděli JSR 175 - Metadata Facility for Java alias Anotace v akci. Já jsem zatím používal pouze klasické SE anotace pro přidání metadat kompilátoru jako @override. Místo kde byly s anotacemi velké plány a kde se od něj hodně slibuje je enterprise oblast. Pokud jste neviděli nějaký příklad EJB 3.0, tak tam se metadata používají pro anotování session i entity bean.

Při studiu frameworku Seam, který je na anotacích postavený jsem ovšem dostal pocit, že XML peklo bude možná nahrazeno anotačním peklem. Seam umožňuje spojení technologie EJB 3.0 a JSF. Mezi jednu z výhod Seamu patří přímé napojení JSF komponent na session beany (action listenery) a entity beany (model) bez nutnosti psaní controleru. Funkce controlleru není nahrazena žádnou automagií, ale anotacemi.

Pokud tedy použijete Seam, ve vašem kódu se to krom EJB anotací začne míhat pěknou řádkou Seam anotací, například pro definici komponent, nastavení/čtení atributů komponent, validaci, transakce atd. Takový jednoduchý kód pak může vypadat následovně (zkopírováno ze Seam dokumentace ).

    
@Stateful
@Scope(SESSION)
@Name("messageManager")
public class MessageManagerBean implements Serializable, MessageManager
{

   @DataModel                                   (1)
   private List<Message> messageList;
   
   @DataModelSelection                          (2)
   @Out(required=false)                         (3)
   private Message message;
   
   @PersistenceContext(type=EXTENDED)           (4)
   private EntityManager em;
   
   @Factory("messageList")                      (5)
   public void findMessages()
   {
      messageList = em.createQuery("from Message msg order by msg.datetime desc").getResultList();
   }
   
   public void select()                         (6)
   {
      message.setRead(true);
   }
   
   public void delete()                         (7)
   {
      messageList.remove(message);
      em.remove(message);
      message=null;
   }
   
   @Remove @Destory                              (8)
   public void destroy() {}

}    
    
    
  1. The @DataModel annotation exposes an attibute of type java.util.List to the JSF page as an instance of javax.faces.model.DataModel. This allows us to use the list in a JSF <h:dataTable> with clickable links for each row. In this case, the DataModel is made available in a session context variable named messageList.
  2. The @DataModelSelection annotation tells Seam to inject the List element that corresponded to the clicked link.
  3. The @Out annotation then exposes the selected value directly to the page. So ever time a row of the clickable list is selected, the Message is injected to the attribute of the stateful bean, and the subsequently outjected to the event context variable named message.
  4. This stateful bean has an EJB3 extended persistence context. The messages retrieved in the query remain in the managed state as long as the bean exists, so any subsequent method calls to the stateful bean can update them without needing to make any explicit call to the EntityManager.
  5. The first time we navigate to the JSP page, there will be no value in the messageList context variable. The @Factory annotation tells Seam to create an instance of MessageManagerBean and invoke the findMessages() method to initialize the value. We call findMessages() a factory method for messages.
  6. The select() action listener method marks the selected Message as read, and updates it in the database.
  7. The delete() action listener method removes the selected Message from the database.
  8. All stateful session bean Seam components must have a method marked @Remove @Destroy to ensure that Seam will remove the stateful bean when the Seam context ends, and clean up any server-side state.

Jenom dodávám, že tohle je opravdu jednoduchý příklad použití. Celkově Seam definuje něco přes třicet anotací! K tomu si připočítejte EJB anotace a to především anotace pro JPA (Java Persistence API) a pravděpodobně se dostaneme někam k stovce runtime metadat. To už je celkem pekelná síla. Co s tím?

  • potřebujeme vylepšit naše vývojové nástroje o rozumnou vizualizaci metadat a podporu vývojových činností jako je refaktorování.
  • vývojáři budou potřebovat návrhové vzory pro použití anotací

Musím říci, že například v případu Spring frameworku dávám přednost starému klasickému XML před anotacemi a to především ze dvou důvodů.

  • centralizace - související metadata mám na jedno místě například definici DAO či WEB vrstvy, to činí práci (hládní, změny) jednoduší.
  • nazávislost - změna metadat nemusí nutně znamenat zásah do kódu aplikace. Mohu mít například pro testování DAO vrstvy v izolaci vlastní nastavení transakcí jenom na úrovni metadat.

Využití anotací je široké, tak hlavně aby z toho nebylo další peklo...