Burak
Burak

Reputation: 155

How to throw Business Exception in Service using Spring AOP?

I have some custom business exceptions in service class and I want to create a target-method exception annotation to remove the duplicate codes but I'm new to Spring AOP. Here's my method;

@Override
public GaDTO execute(String gId, Integer pN) {
    Ga ga = repository.findById(gId);
    if (ga == null){
        throw new GaNotFoundException(gId);
    }
    if (ga.getIniVal().get(N_OF_P) <= pN){
        throw new PNExceedLimitException(gId);
    }
    if ((PTEnum.P_1.equals(ga.getPT()) && ga.getP1().getP().get(pN).getS() == 0)
            || (PTEnum.P_2.equals(ga.getPT()) && ga.getP2().getP().get(pN).getS() == 0)){
        throw new InPException(gId);
    }
    GaDTO gaDTO = gaMapper.toDTO(ga);
    rls.forEach(rl -> rl.apply(gaDTO, pN));
    repository.save(gaMapper.toEntity(gaDTO));
    return gaDTO;
}

I want to create annotations for GaNotFoundException, PNExceedLimitException and InPException. How can I achieve this?

Upvotes: 0

Views: 686

Answers (1)

Niyazi Ekinci
Niyazi Ekinci

Reputation: 87

Firstly, you must add spring-aopdependency to your pom.xml. Here is maven dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

After, you should create an annotation which points business logic exceptions.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BusinessLogicAnnotation {

}

And then you should create Aspect class which handles errors if it exists. Like below

@Aspect
@Component
public class BusinessLogicAspect {

    @Around("@annotation(BusinessLogicAnnotation)")
    public Object businessLogicAspect(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        Ga ga = (Ga) proceed;
        if (ga == null){
            throw new GaNotFoundException(gId);
        }
        if (ga.getIniVal().get(N_OF_P) <= pN){
            throw new PNExceedLimitException(gId);
        }
        if ((PTEnum.P_1.equals(ga.getPT()) && ga.getP1().getP().get(pN).getS() == 0)
                || (PTEnum.P_2.equals(ga.getPT()) && ga.getP2().getP().get(pN).getS() == 0)){
            throw new InPException(gId);
        }
        return proceed;
    }
}

Lastly, you should annotate repository method or service method with annotation that we created.

@Repository
public interface GaRepository extends CrudRepository<Ga, UUID> {
    @BusinessLogicAnnotation
    Ga findByGaId(UUID id);
}

And simplify your service logic:

@Override
public GaDTO execute(String gId, Integer pN) {
    Ga ga = repository.findByGaId(gId);
    GaDTO gaDTO = gaMapper.toDTO(ga);
    rls.forEach(rl -> rl.apply(gaDTO, pN));
    repository.save(gaMapper.toEntity(gaDTO));
    return gaDTO;
}

Upvotes: 1

Related Questions