是的,你可以通過AspectJ。
這是一個獨立的獨立代碼示例。你可以複製和粘貼類和方面並運行它。我沒有使用原來的Hibernate類,但是一些虛擬的替代品,因爲我不是一個Hibernate用戶,我也想使這個通用的答案:
假人,冬眠般的接口和類:
package de.scrum_master.app;
public interface Criterion {}
package de.scrum_master.app;
public class MyCriterion implements Criterion {
private String criterion;
public MyCriterion(String criterion) {
this.criterion = criterion;
}
@Override
public String toString() {
return "MyCriterion [criterion=" + criterion + "]";
}
}
package de.scrum_master.app;
import java.util.List;
public interface Criteria {
Criteria add(Criterion criterion);
List list();
Criteria setFirstResult(int firstResult);
Criteria setMaxResults(int maxResults);
}
package de.scrum_master.app;
import java.util.LinkedList;
import java.util.List;
public class MyCriteria implements Criteria {
private List<Criterion> criteria = new LinkedList<>();
@Override
public Criteria add(Criterion criterion) {
criteria.add(criterion);
return this;
}
@Override
public List list() {
return new LinkedList();
}
@Override
public Criteria setFirstResult(int firstResult) {
add(new MyCriterion("first result " + firstResult));
return this;
}
@Override
public Criteria setMaxResults(int maxResults) {
add(new MyCriterion("max results " + maxResults));
return this;
}
@Override
public String toString() {
return "MyCriteria [criteria=" + criteria + "]";
}
}
正如你所看到的,方法setFirstResult(..)
和setMaxResults(..)
添加特殊標準VI一個add(..)
到內部列表。我只是做了這個以便稍後說明方面的效果。
分頁註釋:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Paginate {}
驅動程序:
package de.scrum_master.app;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Application {
@Paginate
public List filter(Set<Criterion> filter, Map<String, String> alias) {
Criteria criteria = new MyCriteria();
for (Criterion criterion : filter)
criteria.add(criterion);
return criteria.list();
}
public static void main(String[] args) {
Set<Criterion> filterCriteria = new HashSet<>();
filterCriteria.add(new MyCriterion("where"));
filterCriteria.add(new MyCriterion("group by"));
new Application().filter(filterCriteria, null);
}
}
應用程序包含由@Paginate
註釋的方法,做類似的事情,你的示例代碼。它不會調用任何分頁方法。這將通過以下方面完成。
分頁方面:
package de.scrum_master.aspect;
import java.util.List;
import de.scrum_master.app.Paginate;
import de.scrum_master.app.Criteria;
public aspect PaginationAspect {
Object around(Criteria criteria) :
call(public List Criteria+.list()) &&
cflow(execution(@Paginate * *(..))) &&
target(criteria)
{
System.out.println(thisJoinPoint);
System.out.println("Original criteria: " + criteria);
criteria.setFirstResult(5);
criteria.setMaxResults(10);
System.out.println("Modified criteria: " + criteria);
return proceed(criteria);
}
}
切入點攔截調用Criteria+.list()
(所述+
包括亞類),但在由@Paginate
註釋任何執行方法的控制流程(cflow()
)發出時纔可用。調用目標綁定到參數Criteria criteria
,以便在綁定到該切入點的通知方法中使用它。我們需要對調用目標的引用,因爲我們想要調用它的分頁方法。這是建議所做的事情,控制檯輸出清楚地說明了這一點。
控制檯輸出:
call(List de.scrum_master.app.Criteria.list())
Original criteria: MyCriteria [criteria=[MyCriterion [criterion=group by], MyCriterion [criterion=where]]]
Modified criteria: MyCriteria [criteria=[MyCriterion [criterion=group by], MyCriterion [criterion=where], MyCriterion [criterion=first result 5], MyCriterion [criterion=max results 10]]]
享受!
請通過添加說明您的問題的可執行示例代碼來更新您的問題,然後描述所需的結果。這裏的人們喜歡討論具體的編程問題。你更有可能以這種方式得到很好的答案。 – kriegaex 2014-10-21 10:33:38
謝謝你的建議;我修改了我的問題。 – nuno 2014-10-21 10:50:21