0

I am creating AspectJExpressionPointcutAdvisor based on number of pointcut present in application properties file .It's creating object without error but pointcut are not triggered.

Note: Need to create bean dynamically based on number of pointcut expression in properties file (varies).

Application properties file

pointcut.expression.projectUpdate[0]= execution(* com.abc.app.service.impl.TestServiceImpl.updateProjectDetails(..))
pointcut.expression.projectUpdate[1]= execution(* com.abc.app.service.impl.TestServiceImpl.cancelProject(..))
pointcut.expression.projectUpdate[2]= execution(* com.abc.app.service.impl.TestCSATRatingServiceImpl.saveRatingDetails(..))

TestConfig.class

@Configuration
public class TestConfig implements BeanFactoryAware {
    
    @Autowired
    private PointcutExprProperties pcExprProp;
    
    @Autowired(required=false)
    private ProjectUpdateAspect projectUpdateAdvice;

     private BeanFactory beanFactory;
    
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
    
    @PostConstruct
    public void configure() {
        ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
        int i=1;
        for(String pointCut : pcExprProp.getProjectUpdate()) {
            AspectJExpressionPointcutAdvisor projectUpdateAdvisor = new AspectJExpressionPointcutAdvisor();
            projectUpdateAdvisor.setExpression(pointCut);
            projectUpdateAdvisor.setAdvice(projectUpdateAdvice);
            configurableBeanFactory.registerSingleton("beanName_"+i, projectUpdateAdvisor);
            i++;
        }
    }
}

ProjectUpdateAspect.class

@Component
@Aspect
public class ProjectUpdateAspect implements AfterReturningAdvice {

    private static final Logger log = LoggerFactory.getLogger(ProjectUpdateAspect.class);

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        try {
            // some thing
        }catch (Exception exception) {
            log.error("Error while processing ProjectUpdateAspect",exception);
        }

    }
}

PointcutExprProperties

@Configuration
@ConfigurationProperties(prefix = "pointcut.expression")
@Validated
public class PointcutExprProperties {

    @NotNull
    private List<String> projectCreate;
    
    @NotNull
    private List<String> projectUpdate;

    public List<String> getProjectCreate() {
        return projectCreate;
    }

    public void setProjectCreate(List<String> projectCreate) {
        this.projectCreate = projectCreate;
    }

    public List<String> getProjectUpdate() {
        return projectUpdate;
    }

    public void setProjectUpdate(List<String> projectUpdate) {
        this.projectUpdate = projectUpdate;
    }
}

Please suggest me how to get rid of this issue.

  • if you'd forget about `properties` file for a moment, and just created those aspects via hand-written code - would that aspect be triggered? this will help you isolate 'property-resolving issues' from actual implementation issues – 62mkv Mar 08 '21 at 18:43
  • Yes it's triggered when I create individual bean with out property file reference but how to create beans dynamically based on property file? – Raghuveer A.R. Mar 09 '21 at 04:52
  • so if you would have same _single_ pointcut expression, written in a properties file, that is working for you with the non-properties (hand written) approach, and added a log statement inside the loop in `@PostConstruct` method, what'd you see then? if the code really gets there and the property value is exactly the same, then I would be surprised. Usually problems with the properties are either that those are not found, or misread (due to resolving, for example) – 62mkv Mar 09 '21 at 06:09
  • Does this answer your question? [Spring: register advice programmatically at runtime](https://stackoverflow.com/questions/49072611/spring-register-advice-programmatically-at-runtime) – kriegaex Mar 15 '21 at 11:10

1 Answers1

0

I suggest you do it like this:

  • You do not define your "aspect" as @Component @Aspect but make it implement MethodInterceptor.
  • You create AspectJExpressionPointcut with the value from your properties file.
  • You register a DefaultPointcutAdvisor (configured with your pointcut and interceptor) as a bean.

See also my answer here (update 3) and my GitHub sample repository which I just updated for you in order to include reading the pointcut from application.properties.

kriegaex
  • 63,017
  • 15
  • 111
  • 202