2012-05-15 4 views
17

Я использую Spring Framework транзакционных аннотаций для сделки управляющей и я абстрактный класс аннотированный @Transactional, как показано ниже:Возможно ли класс наследовать annotaions из суперкласса

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; 

    } 
} 

Кроме того, у меня есть еще один конкретный класс

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"); 
    } 

} 

Если вы заметили, что студент метод регистра уже предоставил код для изучения аннотаций, где я действительно найти аннотацию @Transactional.

Это противоречие, когда у меня есть другая ссылка, посвященная наследованию аннотаций, и в ней говорится, что наследования нет вообще.

отзыва ссылка: http://fusionsoft-online.com/articles-java-annotations.php

Может кто-нибудь помочь мне решить это противоречие?

ответ

14

Наследование аннотаций работает в основном так же, как наследование методов или полей.

Так как вы можете получить доступ к аннотациям только через отражение, существует два основные метода в Class:

  • getAnnotations() возвращают все аннотации на текущем классе и его супер-классы
  • getDeclaredAnnotations() возвращает все аннотации текущего класса

проблема в статье вы связаны разговоры о том, что Method#getAnnotation(...) доступ declaredAnnotations() класса й e метод, который, как указано выше, возвращает только аннотации, определенные в этом классе, а не в суперклассах.

Это означает, что если вы переопределить один из методов, аннотированных @Transactional Вы должны были бы добавить аннотацию там (или если рамки также выглядит в классе аннотаций он должен найти @Transactional заявил AbstractMaqraaService).

29

Да, это возможно, если к аннотации добавлено @Inherited. Например, аннотация @Transactional имеет @Inherited.

Из документов:

Указывает, что тип аннотации автоматически передается по наследству. Если в объявлении аннотации присутствует аннотация аннотации , пользователь запрашивает тип аннотации в объявлении класса , а объявление класса не имеет аннотации для этого типа , тогда суперкласс класса будет автоматически запрашиваться для тип аннотации. Этот процесс будет повторяться до тех пор, пока не будет найден аннотация для этого типа, или верхняя часть иерархии классов (Object) будет равна . Если суперкласс не имеет аннотации для этого типа, то запрос будет указывать, что этот класс не имеет такой аннотации.

Обратите внимание, что этот тип мета-аннотации не действует, если аннотированный тип используется для аннотирования чего-либо иного, кроме класса. Также обратите внимание, что эта мета-аннотация только вызывает наследование аннотаций от суперклассов; аннотации на реализованные интерфейсы не влияют.

Docs из @Transactional:

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

Off тему: Вы не можете подтип аннотацию, хотя в Java.

+0

Обратите внимание, что @Inherited работает только при применении к классу (а не к методу или интерфейсу) – AlexO

Смежные вопросы