2012-05-15 11 views
17

que estoy usando Spring Framework anotaciones de transacción para la transacción de gestión y he anotado una clase abstracta @Transactional como se ve a continuación:¿Es posible que la clase herede los annotaions de la superclase

package org.tts.maqraa.service; 

import java.util.Collection; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Set; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityNotFoundException; 
import javax.persistence.PersistenceContext; 
import javax.persistence.PersistenceContextType; 
import javax.persistence.Query; 

import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

/** 
* Parts of this code have been copied from JARVANA site. 
* 
* @author Younis alomoush 
* 
*/ 
@Transactional(propagation=Propagation.REQUIRED) 
public abstract class AbstractMaqraaService implements MaqraaService { 


    private Logger logger = LoggerFactory.getLogger(this.getClass()); 


    private int defaultMaxResults = DEFAULT_MAX_RESULTS; 

    @PersistenceContext(type=PersistenceContextType.TRANSACTION) 
    private EntityManager em; 
    /** 
    * The {@link EntityManager} which is used by all query manipulation and 
    * execution in this DAO. 
    * 
    * @return the {@link EntityManager} 
    */ 
    public EntityManager getEntityManager(){ 

     return em; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#getTypes() 
    */ 
    public abstract Set<Class<?>> getTypes(); 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#store(java.lang.Object) 
    */ 
    @Transactional(propagation = Propagation.REQUIRED) 
    public <T extends Object> T store(T toStore) { 
     return getEntityManager().merge(toStore); 

    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#remove(java.lang.Object) 
    */ 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void remove(Object toRemove) { 
     toRemove = getEntityManager().merge(toRemove); 
     getEntityManager().remove(toRemove); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#flush() 
    */ 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void flush() { 
     getEntityManager().flush(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#refresh(java.lang.Object) 
    */ 
    @Transactional(propagation = Propagation.SUPPORTS) 
    public void refresh(Object o) { 
     try { 
      if (o != null) { 
       if (o instanceof java.util.Collection) { 
        for (Iterator<?> i = ((Collection<?>) o).iterator(); i 
          .hasNext();) { 
         try { 
          refresh(i.next()); 
         } catch (EntityNotFoundException x) { 
          // This entity has been deleted - remove it from the 
          // collection 
          i.remove(); 
         } 
        } 
       } else { 
        if (getTypes().contains(o.getClass())) { 
         getEntityManager().refresh(o); 
        } 
       } 
      } 
     } catch (EntityNotFoundException x) { 
      // This entity has been deleted 
     } 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#setDefaultMaxResults(int) 
    */ 
    @Transactional(propagation = Propagation.SUPPORTS) 
    public void setDefaultMaxResults(int defaultMaxResults) { 
     this.defaultMaxResults = defaultMaxResults; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#getDefaultMaxResults() 
    */ 
    public int getDefaultMaxResults() { 
     return defaultMaxResults; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByNameSingleResult(java 
    * .lang.String) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> T executeQueryByNameSingleResult(String queryName) { 
     return (T) executeQueryByNameSingleResult(queryName, (Object[]) null); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByNameSingleResult(java 
    * .lang.String, java.lang.Object[]) 
    */ 

    @SuppressWarnings("unchecked") 
    public <T extends Object> T executeQueryByNameSingleResult(
      String queryName, Object... parameters) { 
     Query query = createNamedQuery(queryName, DEFAULT_FIRST_RESULT_INDEX, 
       1, parameters); 
     return (T) query.getSingleResult(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String) 
    */ 
    public <T extends Object> List<T> executeQueryByName(String queryName) { 
     return executeQueryByName(queryName, DEFAULT_FIRST_RESULT_INDEX, 
       getDefaultMaxResults()); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String, 
    * java.lang.Integer, java.lang.Integer) 
    */ 

    public <T extends Object> List<T> executeQueryByName(String queryName, 
      Integer firstResult, Integer maxResults) { 
     return executeQueryByName(queryName, firstResult, maxResults, 
       (Object[]) null); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String, 
    * java.lang.Object[]) 
    */ 

    public <T extends Object> List<T> executeQueryByName(String queryName, 
      Object... parameters) { 
     return executeQueryByName(queryName, DEFAULT_FIRST_RESULT_INDEX, 
       getDefaultMaxResults(), parameters); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String, 
    * java.lang.Integer, java.lang.Integer, java.lang.Object[]) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> List<T> executeQueryByName(String queryName, 
      Integer firstResult, Integer maxResults, Object... parameters) { 
     Query query = createNamedQuery(queryName, firstResult, maxResults, 
       parameters); 
     return query.getResultList(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#createNamedQuery(java.lang.String, 
    * java.lang.Integer, java.lang.Integer) 
    */ 

    public Query createNamedQuery(String queryName, Integer firstResult, 
      Integer maxResults) { 
     return createNamedQuery(queryName, firstResult, maxResults, 
       (Object[]) null); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#createNamedQuery(java.lang.String, 
    * java.lang.Integer, java.lang.Integer, java.lang.Object[]) 
    */ 

    public Query createNamedQuery(String queryName, Integer firstResult, 
      Integer maxResults, Object... parameters) { 
     Query query = getEntityManager().createNamedQuery(queryName); 
     if (parameters != null) { 
      for (int i = 0; i < parameters.length; i++) { 
       query.setParameter(i + 1, parameters[i]); 
      } 
     } 

     query.setFirstResult(firstResult == null || firstResult < 0 ? DEFAULT_FIRST_RESULT_INDEX 
       : firstResult); 
     if (maxResults != null && maxResults > 0) 
      query.setMaxResults(maxResults); 

     return query; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#executeQuery(java.lang.String, 
    * java.lang.Integer, java.lang.Integer, java.lang.Object[]) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> List<T> executeQuery(String queryString, 
      Integer firstResult, Integer maxResults, Object... parameters) { 
     Query query = createQuery(queryString, firstResult, maxResults, 
       parameters); 
     return query.getResultList(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#executeQuery(java.lang.String, 
    * java.lang.Object[]) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> List<T> executeQuery(String queryString, 
      Object... parameters) { 
     Query query = createQuery(queryString, DEFAULT_FIRST_RESULT_INDEX, 
       getDefaultMaxResults(), parameters); 
     return query.getResultList(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQuerySingleResult(java.lang. 
    * String) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> T executeQuerySingleResult(String queryString) { 
     return (T) executeQuerySingleResult(queryString, (Object[]) null); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * org.skyway.spring.util.dao.JpaDao#executeQuerySingleResult(java.lang. 
    * String, java.lang.Object[]) 
    */ 
    @SuppressWarnings("unchecked") 
    public <T extends Object> T executeQuerySingleResult(String queryString, 
      Object... parameters) { 
     Query query = createQuery(queryString, DEFAULT_FIRST_RESULT_INDEX, 1, 
       parameters); 
     return (T) query.getSingleResult(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#createQuery(java.lang.String, 
    * java.lang.Integer, java.lang.Integer) 
    */ 

    public Query createQuery(String queryString, Integer firstResult, 
      Integer maxResults) { 
     return createQuery(queryString, firstResult, maxResults, 
       (Object[]) null); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.skyway.spring.util.dao.JpaDao#createQuery(java.lang.String, 
    * java.lang.Integer, java.lang.Integer, java.lang.Object[]) 
    */ 
    public Query createQuery(String queryString, Integer firstResult, 
      Integer maxResults, Object... parameters) { 
     Query query = getEntityManager().createQuery(queryString); 
     if (parameters != null) { 
      for (int i = 0; i < parameters.length; i++) { 
       query.setParameter(i + 1, parameters[i]); 
      } 
     } 

     query.setFirstResult(firstResult == null || firstResult < 0 ? DEFAULT_FIRST_RESULT_INDEX 
       : firstResult); 
     if (maxResults != null && maxResults > 0) 
      query.setMaxResults(maxResults); 

     return query; 
    } 

    public final void log(LogLevel logLevel, String message, 
      Object... messageParam) { 

     switch (logLevel) { 
     case TRACE: 
      if (logger.isTraceEnabled()) { 

       logger.trace(message, messageParam); 
      } 

      break; 

     case DEBUG: 
      if (logger.isDebugEnabled()) { 

       logger.debug(message, messageParam); 
      } 
      break; 

     case INFO: 
      if (logger.isInfoEnabled()) { 

       logger.info(message, messageParam); 
      } 
      break; 

     case WARN: 
      if (logger.isWarnEnabled()) { 

       logger.warn(message, messageParam); 
      } 
      break; 

     case ERROR: 
      if (logger.isErrorEnabled()) { 

       logger.error(message, messageParam); 
      } 
      break; 

     default: 
      throw new IllegalArgumentException("Log Level is not defined: " 
        + logLevel); 

     } 

    } 

    public final void log(LogLevel logLevel, String message, Throwable throwable) { 

     switch (logLevel) { 
     case TRACE: 
      if (logger.isTraceEnabled()) { 

       logger.trace(message, throwable); 
      } 

      break; 

     case DEBUG: 
      if (logger.isDebugEnabled()) { 

       logger.debug(message, throwable); 
      } 
      break; 

     case INFO: 
      if (logger.isInfoEnabled()) { 

       logger.info(message, throwable); 
      } 
      break; 

     case WARN: 
      if (logger.isWarnEnabled()) { 

       logger.warn(message, throwable); 
      } 
      break; 

     case ERROR: 
      if (logger.isErrorEnabled()) { 

       logger.error(message, throwable); 
      } 
      break; 

     default: 
      throw new IllegalArgumentException("Log Level is not defined: " 
        + logLevel); 

     } 

    } 


    public enum LogLevel{ 

     TRACE, DEBUG, INFO, WARN, ERROR; 

    } 
} 

Además, tengo otra clase concreta

package org.tts.maqraa.service; 

import java.lang.annotation.Annotation; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 
import org.tts.maqraa.data.Student; 


public class StudentsService extends AbstractMaqraaService { 

    @Override 
    public Set<Class<?>> getTypes() { 
     Set<Class<?>> set = new HashSet<Class<?>>(); 
     set.add(Student.class); 
     return set; 
    } 

    public Student registerStudent(Student student) { 
     Annotation [] annotation = StudentsService.class.getAnnotations(); 
     System.out.println(annotation); 
     return this.store(student); 
    } 

    public Student editStudent(Student student){ 
     return this.store(student); 
    } 

    public void deregisterStudent(Student student){ 
     this.remove(student); 
    } 

    public List<Student> findAllStudents(){ 
     return this.executeQueryByName("Student.findAll"); 
    } 

} 

Si usted nota que el estudiante registro método ya ha proporcionado código para examinar las anotaciones en el que realmente encontrar la anotación @Transactional.

Eso es una contradicción cuando tengo otro enlace que habla sobre la herencia de anotaciones y dice que no hay herencia en absoluto.

opinión este enlace: http://fusionsoft-online.com/articles-java-annotations.php

Puede alguien ayudarme a resolver esta contradicción?

Respuesta

14

La herencia de anotaciones funciona básicamente de la misma manera que la herencia de métodos o campos.

Ya que se puede acceder a las anotaciones sólo a través de la reflexión, hay dos métodos básicos en Class:

  • getAnnotations() devuelve todas las anotaciones en la clase actual y sus súper clases
  • getDeclaredAnnotations() devuelve todas las anotaciones en la clase actual

el problema del artículo que habla sobre enlazadas es que Method#getAnnotation(...) accesos declaredAnnotations() de la clase XX El método se ha definido en, que como se indicó anteriormente solo devuelve las anotaciones definidas en esa clase y no las de las súper clases.

Esto significa que si se reemplaza uno de los métodos anotados con @Transactional habría que añadir la anotación allí (o si los marcos también se ve en la anotación de clase debe encontrar el @Transactional declarado el AbstractMaqraaService).

29

Sí, es posible si se ha agregado la anotación @Inherited. Por ejemplo, la anotación @Transactional tiene @Inherited.

A partir de los documentos:

indica que un tipo de anotación se hereda de forma automática. Si una metaanotación heredada está presente en una declaración de tipo anotación , y el usuario consulta el tipo de anotación en una declaración de clase , y la declaración de clase no tiene anotación para este tipo , se consultará automáticamente la superclase de la clase el tipo de anotación. Este proceso se repetirá hasta que se encuentre una anotación para este tipo, o se llegue a la parte superior de la jerarquía de clases (Objeto) . Si ninguna superclase tiene una anotación para este tipo, la consulta indicará que la clase en cuestión no tiene dicha anotación.

Tenga en cuenta que este tipo de meta-anotación no tiene ningún efecto si el tipo anotado se utiliza para anotar cualquier cosa que no sea una clase. Tenga en cuenta también que esta metaanotación solo hace que las anotaciones se hereden de las superclases ; las anotaciones en las interfaces implementadas no tienen ningún efecto.

Docs de @Transactional:

@Target(value={METHOD,TYPE}) 
@Retention(value=RUNTIME) 
@Inherited 
@Documented 
public @interface Transactional 

Fuera de tema: no se puede subtipo una anotación aunque en Java.

+0

Tenga en cuenta que @Inherited funciona solo cuando se aplica en una clase (no en un método o interfaz) – AlexO

Cuestiones relacionadas