Spring AOP: pointcut @annotation (MyAnnotation) && appel (..) ne se déclenche pas comme prévu

RAM Mercredi:

Je suis en train d'exécuter un code de jeu dans mes conseils mais ne peut pas en mesure de tisser le code dans la fonction qui a l' @SecuredAPIannotation et appelle la setQuery()fonction.

Auparavant, j'ai essayé pointcut suivant et cela a fonctionné très bien

call(* org.elasticsearch.action.search.SearchRequestBuilder.setQuery(org.elasticsearch.index.query.QueryBuilder)) && args(queryBuilder)

Mais le besoin d'inclure également la condition annotée dans ce domaine. S'il vous plaît me aider.

Mes conseils poincut et se présente comme suit

@Around(value = "@annotation(SecuredAPI)  && call(* org.elasticsearch.action.search.SearchRequestBuilder.setQuery(org.elasticsearch.index.query.QueryBuilder)) && args(queryBuilder)" )
public Object decorateQuery(ProceedingJoinPoint proceedingJoinPoint, QueryBuilder queryBuilder) throws Throwable {
  // ...
}

Et ma fonction ressemble à ceci

@SecuredAPI
public List<Integer> getAllIds() {
  // ...
  SearchResponse response = conn
    .getESClient().prepareSearch(ElasticSearchConstants.ATTRIBUTE_INDEX)
    .setSearchType(SearchType.DEFAULT)
    //.setQuery(QueryBuilders.queryStringQuery(searchQuery))
    .setQuery(qb)
    .setFrom(0).setSize(10000).setExplain(true).get();
}

S'il vous plaît aidez-moi à trouver un moyen de peut-il fonctionner pour condition suivante

kriegaex:

D' accord, lors de l' édition de votre question (le formatage du code a été chaotique bits) Je l' ai lu à nouveau et vous avez dit que call()fonctionne réellement pour vous. Donc , vous ne l' utilisez Spring AOP parce call()est pas pris en charge là - bas. Vous devez utiliser AspectJ, probablement par LTW (tissage de charge en temps) ou peut - être par l' intermédiaire CTW (tissage de la compilation). Il ne fait pas de différence pour la réponse.

Le problème est que @annotation(SecuredAPI)cela fait travailler à l' intérieur d' un execution()pointcut défini sur votre méthode annotée, mais la méthode que vous appelez à partir il n'y a pas annotées, de sorte que le conseil ne se déclenche pas call(). Il ne serait si la méthode cible setQuery(..)a été authentifié , mais ce n'est pas. Par conséquent, @annotation()n'est pas le droit pointcut à vos besoins.

Qu'est - ce que vous voulez exprimer est: « un appel à setQuery(..)partir du code annoté par @SecuredAPI». Cela se fait comme suit (exemple AspectJ sans ressort, s'il vous plaît ajuster les noms de classe et de package à vos besoins):

package de.scrum_master.app;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD })
public @interface SecuredAPI {}
package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    Application application = new Application();
    application.doSomething();
    application.doSomethingElse();
  }

  @SecuredAPI
  public void doSomething() {
    System.out.println("Doing something before setting query");
    setQuery("my first query");
    System.out.println("Doing something after setting query");
  }

  public void doSomethingElse() {
    System.out.println("Doing something else before setting query");
    setQuery("my second query");
    System.out.println("Doing something else after setting query");
  }

  public void setQuery(String query) {
    System.out.println("Setting query to: " + query);
  }
}
package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SecuredAPIAspect {
  @Around("@withincode(de.scrum_master.app.SecuredAPI) && call(* setQuery(..))")
  public Object myAdvice(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    System.out.println(thisJoinPoint);
    return thisJoinPoint.proceed();
  }
}

Voir? @withincode()est votre ami dans ce cas. Le journal de la console se présente comme suit:

Doing something before setting query
call(void de.scrum_master.app.Application.setQuery(String))
Setting query to: my first query
Doing something after setting query
Doing something else before setting query
Setting query to: my second query
Doing something else after setting query

En outre, vous devez également utiliser un nom de classe entièrement qualifié pour l'annotation tels que de.scrum_master.app.SecuredAPI, non seulement SecuredAPI, à moins que l'annotation se trouve être dans le même emballage que votre aspect.

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=206040&siteId=1
conseillé
Classement