How should I expose a transactional service, measuring methods invocation times, with separation of concerns in mind?

35 Views Asked by At

I'm working on an application created with SpringBoot. What I'm trying to achieve is a layered application, with separation of concerns in each layer. One of the layers (Gradle module) is an Application layer, where I define an application service:

public class TagApplicationService {

    public TagResult getTag(UUID tagId) {
        ...
    }

    public TagResult createTag(CreateTagCommand createTagCommand) {
        ...
    }
}

In another Gradle module, responsible for setting up Spring context, which depends on the application module, I define a configuration:

@Configuration
@ComponentScan(
        basePackages = "application.tag",
        includeFilters = @ComponentScan.Filter(
                type = FilterType.ASSIGNABLE_TYPE,
                classes = {
                        TagApplicationService.class
                }
        )
)
class ApplicationConfiguration {
}

Having separation of concerns in mind (I don't want the application module to have any Spring/JPA/Micrometer related dependencies), how can I make the produced bean transactional? I would also like to collect metrics about the invocation times of methods of TagApplicationService with Micrometer and expose them with Actuator.

I tried to extend the TagApplicationService in Spring module and make the new class transactional. But I believe there must be a better way. The solution doesn't solve the problem of metrics collection, which I would like not to mix with the responsibility of making the bean transactional.

@Transactional
@Service
class TransactionalTagApplicationService extends TagApplicationService {
    public TagResult getTag(UUID tagId) {
        return super.getTag(tagId);
    }

    public TagResult createTag(CreateTagCommand createTagCommand) {
        return super.createTag(createTagCommand);
    }
}
0

There are 0 best solutions below