Class SpyProxy<T>

  • Type Parameters:
    T - bean type
    All Implemented Interfaces:
    com.google.inject.Provider<T>, jakarta.inject.Provider<T>, javax.inject.Provider<T>, org.aopalliance.aop.Advice, org.aopalliance.intercept.Interceptor, org.aopalliance.intercept.MethodInterceptor

    public class SpyProxy<T>
    extends java.lang.Object
    implements org.aopalliance.intercept.MethodInterceptor, com.google.inject.Provider<T>
    AOP interceptor redirect calls from the real bean into spy object, which was created around the same real bean.

    There is a chicken-egg problem: service binding can't be overridden (with spy instance), because spy requires service instance for construction. So, instead of replacing bean, we intercept bean calls. Actual spy object is created lazily just after injector creation. On the first call, AOP interceptor breaks the current aop chain (if other interceptors registered) and redirect calls to spy, which again calls the same service (including aop handler), but, this time, it processes normally.

    • Constructor Summary

      Constructors 
      Constructor Description
      SpyProxy​(java.lang.Class<T> type)
      Create proxy.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      T get()
      Alternative spy provider to use proxy as Provider<?>.
      T getSpy()  
      java.lang.Class<T> getType()  
      java.lang.Object invoke​(org.aopalliance.intercept.MethodInvocation methodInvocation)  
      void setInstanceProvider​(com.google.inject.Provider<T> instanceProvider)
      Delayed bean instance provider.
      SpyProxy<T> withInitializer​(java.util.function.Consumer<T> initializer)
      Actual spy object instance is created only on first bean access (after or in time of application startup).
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • SpyProxy

        public SpyProxy​(java.lang.Class<T> type)
        Create proxy.
        Parameters:
        type - bean type
    • Method Detail

      • withInitializer

        public final SpyProxy<T> withInitializer​(java.util.function.Consumer<T> initializer)
        Actual spy object instance is created only on first bean access (after or in time of application startup). Normally, it is ok to wait for application startup, configure spy object and then run tests methods (using spy). But if spied bean is involved in application startup (called by some managed objects) then the only way to configure it is to apply modification just after spy instance creation.

        Might be called multiple times (for multiple initializers configuration).

        Parameters:
        initializer - spy object initializer
        Returns:
        proxy instance
      • setInstanceProvider

        public void setInstanceProvider​(com.google.inject.Provider<T> instanceProvider)
        Delayed bean instance provider. Required because a proxy object created before guice modules processing (provider could be obtained from binder).
        Parameters:
        instanceProvider - bean instance provider, used to get bean instance for spying
      • getType

        public java.lang.Class<T> getType()
        Returns:
        proxied bean type
      • getSpy

        public T getSpy()
        Returns:
        spy instance
      • get

        public T get()
        Alternative spy provider to use proxy as Provider<?>. Internally, this method is not used as it is hard to search usages for it.
        Specified by:
        get in interface com.google.inject.Provider<T>
        Specified by:
        get in interface jakarta.inject.Provider<T>
        Specified by:
        get in interface javax.inject.Provider<T>
        Returns:
        spy instance
      • invoke

        public java.lang.Object invoke​(org.aopalliance.intercept.MethodInvocation methodInvocation)
                                throws java.lang.Throwable
        Specified by:
        invoke in interface org.aopalliance.intercept.MethodInterceptor
        Throws:
        java.lang.Throwable