@Before方面未在实际服务方法中反映修改后的值

时间:2019-01-15 11:37:23

标签: aop aspectj spring-aop

我有如下服务方法。我已经实现了@Before方面,其中根据某些条件修剪了字符串参数,但是当控件从方面返回到服务方法时,修改后的值不会反映出来。

我希望修剪后的dataNumber应该去db;之前它工作正常,但从ceratin开始,它停止工作。我已经调试了代码,控件首先进入服务方法,然后进入方面,修剪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 :(得分:0)

您不能在@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)]