简体   繁体   中英

Spring : Interception without AspectJ

In my Spring 4 application, I have a class like this:

class Address {

   public getAdress(){
      ...
      List<Town> towns = getTowns();
      ...
   }

   @CustomAnnotation
   private List<Town> getTowns(){

   }
}

With AspectJ I can easily intercept the getAdress() call. The problem is with getTowns() that is not intercepted.

There are solutions such as Load-Time Weaving but that is difficult to tune and I don't what to reconfigure my application.

How can I capture any call made to any method annotated with CustomAnnotation without AspectJ ?

Regards

PS: I know that there is a workaround with self-reference but I don't find it very "clean".

Extracting interface:

interface TempIfc{
    public getAdress();
}

class Address implements TempIfc{

   @Override
   public getAdress(){
      ...
      List<Town> towns = getTowns();
      ...
   }

   @CustomAnnotation
   private List<Town> getTowns(){

   }
}

Adding config:

<bean id="tgt" class="Address">
    <!-- your bean properties here -->
</bean>

<bean id="proxified" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces" value="TempIfc"/>
    <property name="target" ref="tgt"/>
    <property name="interceptorNames">
        <list>
            <value>myInterceptor</value>
        </list>
    </property>
</bean> 

<bean id="myInterceptor" class="MyMethodInterceptor"/>

<!-- Example of usage with some service -->
<bean id="someYourService" class="Service">
     <property name="adress" ref="proxified" />
</bean>

And finally interceptor:

public class MyMethodInterceptor implements  org.aopalliance.intercept.MethodInterceptor{

    public Object invoke(org.aopalliance.intercept.MethodInvocation invocation){

        System.out.println("Before calling any TempIfc method ");

        // Actionally, you may use getMethod, getArguments here to explore details, or modify arguments

        Object result = invocation.proceed(); //also it is not obligatory to call real method

        System.out.println("After calling any TempIfc method ");
        //you may modify result of invocation here

        return result;
    }
}

Here is the docs and javadocs about ProxyFactoryBean.

I think we can use ControlFlowPointcut provided by Spring.

ControlFlowPointcut looks at stacktrace and matches the pointcut only if it finds a particular method in the stacktrace. essentially pointcut is matched only when a method is called in a particular context.

In this case, we can create a pointcut like

ControlFlowPointcut cf = new ControlFlowPointcut(MyClass.class, "method1");

now, using ProxyFactory create a proxy on MyClass instance and call method1().

In above case, only method2() will be advised since it is called from method1().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM