如何使用AspectJ处理通用结果?

时间:2013-02-27 11:04:08

标签: generics aspectj

我有一个方面(用aspectj语法public aspect ....编写),它操纵返回Collection的许多方法的结果,以便对结果进行分页。

我不能(或者我不知道如何)在建议中使用泛型,所以无论我在何处调用建议的方法之一,我都会收到警告

unchecked conversion when advice applied at shadow method-call(java.util.Collection ...), expected java.util.Collection<T> but advice uses java.util.Collection [Xlint:uncheckedAdviceConversion]

我怎样摆脱这个?

斯特凡诺

- 添加方面代码摘录

public aspect PaginationSupportAspect extends ServiceSupportAspect {

    private static final Logger log = LoggerFactory.getLogger(PaginationSupportAspect.class);

    private pointcut paginate(Criteria criteria) : call(Collection org.jcz.persistence.Service+.*(Criteria));

    @SuppressWarnings({ "unchecked", "rawtypes" })
    Collection around(Criteria criteria, Service service) : paginate(criteria) && target(service) {
        log.trace(String.format("Executing <%s> @ <%s>", this.getClass(), thisJoinPoint.toLongString()));

        return doPaginate(proceed(criteria, service), criteria.getPagination(), service);
    }

    /**
     * 
     * @param source
     * @param criteria
     * @return
     */
    private <T extends EntitySupport> Collection<T> doPaginate(Collection<T> source, Pagination pagination, Service<T> service) {
        // IMPLEMENTATION OMITTED BECAUSE IT'S QUITE LONG

        // What it does is to create another Collection<T> that holds the pagination coordinates (page number, size, count) 
        // and only the elements of the requested page
    }

}

用法示例

Collection<MyEntity> entities = myEntityService.findAll(criteria);

这就是我收到警告的地方

1 个答案:

答案 0 :(得分:1)

坏消息:我不知道如何避免警告,因为我对Java泛型不太熟练,特别是与AspectJ没有关系,因为没有你可能期望的所有语法允许,例如将target()绑定到参数化类型(因为类型擦除限制)。

你可能在AspectJ邮件列表上遇到与this one相同的问题。

好消息:我终于设法使用最少的代码示例重现您的问题,使用了大量的虚拟类,对您在应用程序中如何使用它们做了一些有根据的猜测:

虚拟/助手课程/方面:

package org.jcz.persistence;
public class EntitySupport {}
package org.jcz.persistence;
public class MyEntity {}
package org.jcz.persistence;
public class Pagination {}
package org.jcz.persistence;

public class Criteria {
    public Pagination getPagination() {
        return new Pagination();
    }
}
package org.jcz.persistence;

import java.util.ArrayList;
import java.util.Collection;

public class Service<T> {
    public Collection<T> findAll(Criteria criteria) {
        return new ArrayList<T>();
    }
}
package org.jcz.persistence;
public abstract aspect ServiceSupportAspect {}

您的方面略有改变:

package org.jcz.persistence;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.log4j.Logger;

public aspect PaginationSupportAspect extends ServiceSupportAspect {
    private static final Logger log = Logger.getLogger(PaginationSupportAspect.class);

    private pointcut paginate(Criteria criteria) :
        call(Collection org.jcz.persistence.Service+.*(Criteria)) && args(criteria);

    @SuppressWarnings({ "unchecked", "rawtypes" })
    Collection around(Criteria criteria, Service service) : paginate(criteria) && target(service) {
        log.trace(String.format("Executing <%s> @ <%s>", this.getClass(), thisJoinPoint.toLongString()));
        return doPaginate(proceed(criteria, service), criteria.getPagination(), service);
    }

    private <T extends EntitySupport> Collection<T> doPaginate(
            Collection<T> source, Pagination pagination, Service<T> service)
    {
        System.out.println("doPaginate");
        return new ArrayList<T>();
    }
}

现在有一个小型驱动程序应用程序再现Xlint警告:

import java.util.Collection;

import org.jcz.persistence.Criteria;
import org.jcz.persistence.MyEntity;
import org.jcz.persistence.Service;

public class Application {
    public static void main(String[] args) {
        Service<MyEntity> myEntityService = new Service<MyEntity>();
        Criteria criteria = new Criteria();
        Collection<MyEntity> entities = myEntityService.findAll(criteria);
        System.out.println("Found entities: " + entities);
    }
}

也许其他人可以做出我不能做的事情。我能做的最好的就是重现它。我将尝试将安迪克莱门特指向这篇文章。祝你好运!