Home > database >  Spring AOP doesn't work with @Component class
Spring AOP doesn't work with @Component class

Time:11-16

I'm using Spring AOP for exception handling but there is one point that I guess my component class is out of Spring Proxy so Spring AOP annotation that I created doesn't work in that class.

@Configuration
@AllArgsConstructor
public class MGRuleConfig {

    private final GRepository repository;

    private final GInitializer initializer;

    private final GMapper mapper;

    @Bean
    @Qualifier("mRules")
    public List<GRules> mRules(){
        SSRule rule1 = new SSRule();
        CSRule rule2 = new CSRule();
        MPRule rule3 = new MPRule();
        EGRule rule4 = new EGRule();

        return List.of(rule1, rule2, rule3, rule4);
    }

    @Bean
    public GService gService() {
        return new MGServiceImpl(repository, initializer, mapper);
    }
}

Then I have this service;

@Service
@RequiredArgsConstructor
public class MGServiceImpl implements GService {

............

    @Override
    public GaDTO executeRules(String gId, Integer pN) {
        Ga ga = repository.findById(gId);
        GaDTO gaDTO = mapper.toDTO(ga);
        List<GaRules> mRules = (List<GaRules>) applicationContext.getBean("mRules");
        mRules.forEach(rule -> rule.apply(gaDTO, pN));
        repository.save(mapper.toEntity(gaDTO));
        return gaDTO;
    }

I need to put my exception handling annotation into that apply method but aspect doesn't work in that method.

@Component
public class SSRule implements GaRules {

    @Override
    @IPException
    public void apply(GaDTO gaDTO, Integer pN) {
        PDTO p1 = gaDTO.getP1();
        PDTO p2 = gaDTO.getP2();

        if (PTEnum.P_1.equals(gaDTO.getPT())) {
            sS(gaDTO, pN, p1, p2);
        } else {
            sS(gaDTO, pN, p2, p1);
        }
    }

Annotation doesn't work in there. Here's my aspect class;

@Aspect
@Component
public class IPExceptionAspect {

    @Around("execution(public * c.m.s.r.i.SSRule.apply(..)) && "  
            "@annotation(c.m.s.i.a.IPException)")
    public Object checkIP(ProceedingJoinPoint pjp) throws Throwable {
        pjp.proceed();
        return pjp;
    }

}

So, what should I do to make IPException annotation and my Spring AOP work and why doesn't it work?

CodePudding user response:

The problem is your code, you are creating instances of those rules yourself inside a bean method and expose them as a List. Which means the bean is of type List not your own SSRule and thus it won't work.

Instead make an @Bean method, or use the detected instance to inject into the list. As your SSRule is annotated you will already have an instance, just inject that into your @Bean method.

Bean
@Qualifier("mRules")
public List<GRules> mRules(SSRule rule1){
    CSRule rule2 = new CSRule();
    MPRule rule3 = new MPRule();
    EGRule rule4 = new EGRule();

   return List.of(rule1, rule2, rule3, rule4);
}

Now you will get the Spring managed instance which will have AOP applied.

Although I would hardly call this AOP as it is too specific for one class (not really crosscutting in that regard).

  • Related