2012-05-15 88 views
17

我使用Spring框架事務註釋事務管理的超類的annotaions和我有一個抽象類註釋@Transactional,如下圖所示:是否有可能爲類繼承

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(...)訪問類th的declaredAnnotations() e方法已被定義,如上所述,它只返回在該類中定義的註釋而不是超類的註釋。

這意味着,如果重寫與@Transactional註釋的方法之一,你必須添加註釋有(或者如果框架也看在類的註釋應該找到宣佈AbstractMaqraaService@Transactional)。

29

是的,如果註釋添加到@Inherited是可能的。例如,@Transactional註釋具有@Inherited

從文檔:

指示註釋類型被自動繼承。如果 註解類型 聲明中存在繼承的元註釋,並且用戶查詢類 聲明的註釋類型,並且類聲明沒有此 類型的註釋,則將自動查詢該類的超類 註釋類型。此過程將重複進行,直至找到此類型的註釋 ,或者達到類層次結構(對象)的頂部爲 。如果沒有超類具有此類型的註釋,則 查詢將指示所討論的類沒有這種註釋。

請注意,如果帶註釋的 類型用於註釋除類之外的任何其他類型,則此元註釋類型不起作用。還要注意, 這個元註釋只會導致註釋從 超類繼承;已實現的接口上的註釋不起作用。

文檔@Transactional的:

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

題外話:你不能儘管在Java的亞型的註釋。

+0

請注意,@Inherited只適用於應用於類(不是方法或接口) – AlexO

相關問題