@ Перед аспектом не отражаются измененные значения в фактическом методе обслуживания - PullRequest
0 голосов
/ 15 января 2019

У меня есть метод обслуживания, как показано ниже. Я реализовал аспект @Before, в котором строковый аргумент обрезается на основе определенных условий, но когда элемент управления возвращается обратно в сервисный метод из аспекта, измененные значения не отражаются.

Я хочу, чтобы усеченный dataNumber должен идти в БД; Раньше все работало нормально, но, кератино, перестало работать. Я отладил свой код, элемент управления сначала идет в метод службы, а затем переходит к аспекту, обрезает dataNumber, а затем возвращает элемент обратно в метод службы, но аргументы метода не имеют усеченного значения.

@Override
public List<Data> getDataByDataNo(String dataNumber, boolean trim) {
    return getDataByDataNoFromDB(dataNumber, trim);
}

Ниже представлен аспект:

@Aspect
public class TrimDataAspect{
@Before("execution(* com.impl..DataServiceImpl.getDataByDataNo(..)) && args(String,boolean,..)")
public void intrecept(JoinPoint jp) {
    String dataNumber = (String) jp.getArgs()[0];
    if((boolean) jp.getArgs()[1]){
        dataNumber = dataNumber.substring(12);
    }
}

}

1 Ответ

0 голосов
/ 16 февраля 2019

Вы не можете изменить аргументы метода в рекомендации @Before или @After, для этого вам нужно @Around.

Я составил простой пример в чистом AspectJ, но в Spring AOP он работает так же:

package com.impl.whatever;

public class Data {
  private String name;

  public Data(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Data(name=" + name + ")";
  }
}
package com.impl.whatever;

import java.util.ArrayList;
import java.util.List;

public class DataServiceImpl {
  public List<Data> getDataByDataNo(String dataNumber, boolean trim) {
    return getDataByDataNoFromDB(dataNumber, trim);
  }

  public List<Data> getDataByDataNoFromDB(String dataNumber, boolean trim) {
    System.out.println("dataNumber = " + dataNumber);
    List<Data> result = new ArrayList<>();
    result.add(new Data("one"));
    result.add(new Data("two"));
    if (!trim)
      result.add(new Data("three"));
    return result;
  }

  public static void main(String[] args) {
    System.out.println(new DataServiceImpl().getDataByDataNo("Trim, baby! Don't trim this!", false));
    System.out.println(new DataServiceImpl().getDataByDataNo("Trim, baby! Don't trim this!", true));
  }
}

Обратите внимание, как аспект связывает параметры метода с параметрами совета, чтобы избежать использования getArgs(..) и некрасивых приведений.

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 TrimDataAspect {
  @Around("execution(* com.impl..DataServiceImpl.getDataByDataNo(..)) && args(dataNumber, trim, ..)")
  public Object intercept(ProceedingJoinPoint jp, String dataNumber, boolean trim) throws Throwable {
    if (trim)
      dataNumber = dataNumber.substring(12);
    return jp.proceed(new Object[] { dataNumber, trim });
  }
}

Журнал консоли:

dataNumber = Trim, baby! Don't trim this!
[Data(name=one), Data(name=two), Data(name=three)]
dataNumber = Don't trim this!
[Data(name=one), Data(name=two)]
...