Search code examples
javaspringspring-bootspring-aspects

Spring aspect how to update a common field across multiple objects


I am writing a Spring aspect and looking for a way to update a field on the returning object

My Dto's

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class BaseDto{
   LocalDateTime testTime;
}

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TestDto{
  private BaseDto baseDtol
}

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class SampleDto{
  private BaseDto baseDtol
}

My converters classes:

@TestAnnotation
public TestDto covert(){
  return new TestDto()
}

@TestAnnotation
public SampleDto covert(){
  return new SampleDto()
}

Aspect:

@Aspect
@Component
public class TestAspect {
   @AfterReturning(value = "@annotation(TestAnnotation)", returning = "entity")
   public void test(JoinPoint joinPoint, Object entity){
      //Looking for a way to set BaseDto in the TestDto and SampleDto objects
   }
}

My aspect would be called from the converters class and returning objects can be SampleDto and TestDto. I am looking for a way to set the BaseDto object in them.


Solution

  • Edited

    You can use java reflection to dynamically set BaseDto object to entity field.

    1- Iterate through fields of entity.

    • Check fields type (must equal to BaseDto.class)

    2- set accessibility of the checked field to true.

    3- set new BaseDto() to field.

    @AfterReturning(pointcut = "servicePointCut()", returning = "entity")
    public void afterReturningAdvice(JoinPoint joinPoint, Object entity) throws IllegalAccessException 
    
    {
    
        //Iterate through fields of entity
        for (Field field : entity.getClass().getDeclaredFields()) {
    
            //Check type of field (equals to BaseDto.class)
            if (field.getType().equals(BaseDto.class)) {
    
                //Set accessibility of field to true
                field.setAccessible(true);
                
                //Set new BaseDto to entityobject
                BaseDto baseDto = new BaseDto();
                field.set(entity, baseDto);
            }
         
        }
    
     //Rest of afterReturningAdvice method ...
    }