不显眼的AOP用Spring.Net [英] Unobtrusive AOP with Spring.Net

查看:284
本文介绍了不显眼的AOP用Spring.Net的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想补充的登录饰有一个属性的方法使用的 Spring.Net AOP的

步骤1: 参考'Spring.Core','Spring.Aop','Common.Logging'

Step 1: Reference 'Spring.Core', 'Spring.Aop', 'Common.Logging'

步骤2: 创建一个建议:

Step 2: Create an advice:

using AopAlliance.Intercept;

namespace MyApp.Aspects
{
    public class LoggingAdvice : IMethodInterceptor
    {
      public object Invoke(IMethodInvocation invocation)
      {
        //todo: log started
        object rval = invocation.Proceed();
        return rval;
        //todo: log finished
      }
    }
}

第3步:创建一个属性:

Step 3: Create an attribute:

using System;

namespace MyApp.Aspects
{
  public class LoggingAttribute : Attribute
  {
  }
}

第四步:编辑的web.config

Step 4: Edit web.config

<configuration>
  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>

  <spring>
    <context>
      <resource uri="config://spring/objects" />
    </context>

    <objects xmlns="http://www.springfrmework.net">

      <object id="loggingAdvice" type="MyApp.Aspects.LoggingAdvice, MyApp"></object>
      <object id="loggingAdvisor" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
        <property name="Advice" ref="loggingAdvice" />
      </object>

      <object type="Spring.Aop.Framework.AutoProxy.AttributeAutoProxyCreator, Spring.Aop">
        <property name="AttributeTypes" value="MyApp.Aspects.LoggingAttribute"/>
        <property name="InterceptorNames" value="loggingAdvisor"/>
      </object>

    </objects>
  </spring>
</configuration>

第五步:装饰用属性的方法:

Step 5: Decorate a method with the attribute:

using System.Web.Mvc;

namespace MyApp.Controllers
{
  public class MyController : Controller
  {
    [Logging]
    public ActionResult DoStuff()
    {
      //todo: implement
    }
  }
}

建议永远引发。我在想什么?

推荐答案

这必须与所创建的控制器,然后实际调用的事实 DoStuff()上本身。该控制器明显不成立的代理本身,因此调用 DoStuff()没有得到通过Spring.Net AOP拦截。

This has to do with the fact that the controller is created and then actually calls DoStuff() on it self. The controller obviously does not hold a proxy to itself and therefore the call to DoStuff() does not get intercepted by Spring.Net AOP.

由于tobsen提到了他的答案,你将获得从春天控制器,否则拦截不会发生。我假设你正在使用Spring MVC的支持,在这里创建控制器,但这并不能清楚地从你的问题表明,你可能已经离开了出来。

As tobsen mentions in his answer, you will have to get the controller from spring, otherwise interception will not take place. I assume you're using spring mvc support here to create controllers, but this does not clearly show from your question and you might have left it out.

摘要

有关详细信息和示例,请参阅下文。

See below for details and an example.

  1. 使用的 InheritanceBasedAopConfigurer
  2. 您想拦截虚拟
  3. 声明方式
  4. 配置您的拦截器
  1. Use an InheritanceBasedAopConfigurer
  2. Declare methods you want to intercept as virtual
  3. Configure your interceptors

Spring的默认拦截机制不起作用......

当一个请求到MVC应用程序,然后从请求URL控制器的选择是通过MVC框架。在此控制器,执行()方法被调用,这又是负责调用action方法。要认识到的操作方法始终从控制器的内调用是很重要的。

When a request is made to an MVC app, then from the request url a controller is chosen by the MVC framework. On this controller, the Execute() method is called, which in turn is responsible for invoking the action methods. It is important to realize that action methods are always called from within the controller.

Spring.NET AOP采用动态编织。默认情况下,在运行时将代理用于其AOP顾问在配置中声明的对象创建。这个代理拦截电话和呼叫转发到目标实例。这是进行代理时的情形<一个href="http://www.springframework.net/doc-latest/reference/html/aop.html#aop-proxying-interfaces">interfaces和类(使用代理目标型=真正的。当目标对象上调用它自己的方法,它不会通过弹簧代理和方法做到这一点的不会被截获的。这究竟是为什么默认的AOP机制不为MVC控制器的工作。

Spring.NET aop uses dynamic weaving. By default, at runtime a proxy is created for objects for which aop advisors are declared in the configuration. This proxy intercepts calls and forwards calls to the target instance. This is done when proxying interfaces and classes (using proxy-target-type="true"). When the target object invokes a method on it self, it will not do this through the spring proxy and the method does not get intercepted. This why the default aop mechanism doesn't work for mvc controllers.

...但使用 InheritanceBasedAopConfigurer 的伎俩

... but using an InheritanceBasedAopConfigurer does the trick

要拦截行动方法调用,你应该使用<一个href="http://www.springframework.net/doc-latest/reference/html/aop.html#aop-inheritancebasedaopconfigurer"><$c$c>InheritanceBasedAopConfigurer.这将调用基类的方法之前创建一个基于继承的代理,不委托给目标对象,而不是拦截的建议是,在方法体中直接加入。

To intercept calls on action methods, you should use an InheritanceBasedAopConfigurer. This will create an inheritance based proxy that does not delegate to a target object, instead interception advice is added directly in the method body before invoking the base class method.

请注意,对于这种拦截方式工作,方法必须是虚的。

Note that for this interception method to work, the methods have to be virtual.

下面的XML配置如下:

The following xml config works:

<!-- 
When not specifying an object id or name, 
spring will assign a name to it like [typename]#[0,1,2,..]  
-->  
<object type="MyApp.Controllers.HomeController, MyApp" 
        singleton="false" />

<object id="myInterceptor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
  <property name="Attribute" value="MyApp.MyAttribute, MyApp" />
  <property name="Advice">
    <object type="MyApp.MyAdvice, MyApp" />
  </property>
</object>

<object type="Spring.Aop.Framework.AutoProxy.InheritanceBasedAopConfigurer, Spring.Aop">
  <property name="ObjectNames">
    <list>
      <value>*Controller#*</value>
    </list>
  </property>
  <property name="InterceptorNames">
    <list>
      <value>myInterceptor</value>
    </list>
  </property>
</object>

一个工作的例子是<一个href="https://github.com/serra/stackoverflow/tree/master/spring-questions/q9114762_aop_on_mvc_controllers">available在GitHub上。它是基于一个标准的MVC 3应用程序 Spring.Net MVC3支持。相关文件是:

A working example is available on github. It is based on a standard mvc 3 application with Spring.Net Mvc3 support. Relevant files are:

  • <一个href="https://github.com/serra/stackoverflow/blob/master/spring-questions/q9114762_aop_on_mvc_controllers/Config/objects.xml">xml配置
  • <一个href="https://github.com/serra/stackoverflow/blob/master/spring-questions/q9114762_aop_on_mvc_controllers/Controllers/HomeController.cs"><$c$c>HomeController
  • <一个href="https://github.com/serra/stackoverflow/blob/master/spring-questions/q9114762_aop_on_mvc_controllers/Controllers/SetMethodInfoAsMessageAdvice.cs">attribute和拦截
  • xml configuration
  • HomeController
  • attribute and interceptor

参考

  • Spring.net文档:<一href="http://www.springframework.net/doc-latest/reference/html/aop.html#aop-proxying-interfaces">proxying接口的 VS 代理类 VS使用<一个href="http://www.springframework.net/doc-latest/reference/html/aop.html#aop-inheritancebasedaopconfigurer">inheritance基于AOP配置器
  • 有关事务拦截类似的问题在这里:<一href="http://stackoverflow.com/questions/4280143/asp-net-mvc-controller-declarative-aop-with-spring-net/4346791#4346791">Asp.Net MVC控制器:声明AOP与Spring.Net 。溶液可委派调用注射服务或使用基于继承代理,参见马克的回答上述问题。在后一种情况下, DoStuff()应该被声明为虚。
  • <一个href="http://forum.springframework.net/showthread.php?7338-Asp.Net-MVC-Controller-declarative-AOP-with-Spring.Net">spring.net论坛帖子
  • Spring.net docs: proxying interfaces vs proxying classes vs using an inheritance based aop configurer
  • A similar question with regard to transaction interception is here: Asp.Net MVC Controller: declarative AOP with Spring.Net. Solution can be to delegate calls to injected services or to use an inheritance based proxy, see Mark's answer to the question mentioned above. In the latter case DoStuff() should be declared virtual.
  • spring.net forum post

这篇关于不显眼的AOP用Spring.Net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆