类是否可以继承超类的注释

2022-09-01 13:56:17

我正在使用Spring Framework事务注释进行事务管理,并且我有一个注释,如下所示:abstract class@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

谁能帮我解决这个矛盾?


答案 1

是的,如果注释已添加到@Inherited,则可以这样做。例如,@Transactional注释具有 。@Inherited

从文档中:

指示批注类型自动继承。如果批注类型声明上存在继承的元批注,并且用户在类声明上查询该批注类型,并且该类声明没有针对此类型的批注,则将自动查询类的超类以获取该批注类型。将重复此过程,直到找到此类型的批注,或者到达类层次结构(Object)的顶部。如果没有超类具有此类型的注释,则查询将指示所讨论的类没有此类注释。

请注意,如果使用带批注的类型来批注类以外的任何内容,则此元批注类型不起作用。另请注意,此元注释仅导致注释从超类继承;已实现接口上的注释不起作用。

文档 :@Transactional

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

题外话:在 Java 中不能对注释进行子类型化。


答案 2

注释继承的工作方式与方法或字段的继承基本相同。

由于您只能通过反射访问注释,因此在 以下两种基本方法:Class

  • getAnnotations()返回当前类及其超类上的所有批注
  • getDeclaredAnnotations()返回当前类上的所有批注

您链接的文章所讨论的问题是,已定义方法的类的访问,如上所述,该类仅返回该类中定义的注释,而不是超类的注释。Method#getAnnotation(...)declaredAnnotations()

这意味着,如果您重写其中一个带有注释的方法,则必须在那里添加注释(或者如果框架也在类注释中查找,它应该找到声明在 )。@Transactional@TransactionalAbstractMaqraaService


推荐