Class LoggedTargetGuardBeanPostProcessor
- All Implemented Interfaces:
org.springframework.beans.factory.config.BeanPostProcessor
Logged is applied to a method that
cannot be correctly instrumented: a method on a JPA entity, a Spring Data
repository interface implementation, a class annotated with
@Repository, or a method returning a reactive
org.reactivestreams.Publisher (Reactor's Mono/Flux,
or an RxJava adapter that implements the same interface).
Instrumenting an entity or repository is almost always a mistake. Entities are plain data holders whose getters can be invoked extremely frequently (for example during JSON serialization or JPA dirty checking), turning a single request into thousands of log lines and metric updates. Repositories are already covered by lower-level persistence metrics (query timing, connection pool statistics); wrapping every repository call in the same interceptor as business logic tends to blur, rather than clarify, what is slow.
A method returning a reactive Publisher cannot be correctly
instrumented by this library today for a different reason: @Logged
only defers its duration/outcome recording for CompletableFuture, via whenComplete. A
reactive type built with Project Reactor or RxJava is lazy — nothing runs
until something subscribes — so ProceedingJoinPoint#proceed()
returning only means the pipeline was assembled, not that it ran. Silently
recording at that point would report a near-zero duration and
unconditional success regardless of what the reactive pipeline actually
does once subscribed to, which is worse than not measuring it at all: it
looks like real data. Rejecting it at startup is preferred over recording
something misleading; full reactive support (bridging FlowContext
and MDC through Reactor's Context) is a substantially larger
feature, not yet implemented.
This check runs once per bean, before Spring's AOP auto-proxy creator
wraps the bean, so it inspects the original target class rather than a
proxy. It intentionally does not import jakarta.persistence.Entity,
org.springframework.stereotype.Repository,
org.springframework.data.repository.Repository, or
org.reactivestreams.Publisher directly, and instead compares fully
qualified names through reflection. This keeps this module free of a hard
dependency on JPA, Spring Data, or a reactive streams implementation, so
consumers who use none of these are not forced to bring them onto the
classpath.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionpostProcessBeforeInitialization(Object bean, @NonNull String beanName) Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.springframework.beans.factory.config.BeanPostProcessor
postProcessAfterInitialization
-
Constructor Details
-
LoggedTargetGuardBeanPostProcessor
public LoggedTargetGuardBeanPostProcessor()
-
-
Method Details
-
postProcessBeforeInitialization
public Object postProcessBeforeInitialization(Object bean, @NonNull String beanName) throws org.springframework.beans.BeansException - Specified by:
postProcessBeforeInitializationin interfaceorg.springframework.beans.factory.config.BeanPostProcessor- Throws:
org.springframework.beans.BeansException
-