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);
}
}