简体   繁体   English

春季:无AspectJ的拦截

[英]Spring : Interception without AspectJ

In my Spring 4 application, I have a class like this: 在我的Spring 4应用程序中,我有一个像这样的类:

class Address {

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

   @CustomAnnotation
   private List<Town> getTowns(){

   }
}

With AspectJ I can easily intercept the getAdress() call. 使用AspectJ,我可以轻松地拦截getAdress()调用。 The problem is with getTowns() that is not intercepted. 问题在于没有被拦截的getTowns()

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 ? 在没有AspectJ的情况下,如何捕获对任何使用CustomAnnotation注释的方法的调用?

Regards 问候

PS: I know that there is a workaround with self-reference but I don't find it very "clean". PS:我知道有一种使用自引用的解决方法,但是我觉得它不是很“干净”。

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. 这是有关ProxyFactoryBean的文档javadocs

I think we can use ControlFlowPointcut provided by Spring. 我认为我们可以使用Spring提供的ControlFlowPointcut。

ControlFlowPointcut looks at stacktrace and matches the pointcut only if it finds a particular method in the stacktrace. ControlFlowPointcut会查看stacktrace并仅在它在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(). 现在,使用ProxyFactory在MyClass实例上创建一个代理,然后调用method1()。

In above case, only method2() will be advised since it is called from method1(). 在上述情况下,仅建议使用method2(),因为它是从method1()调用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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