gpt4 book ai didi

.net - 使用 Spring.Net 的不显眼的 AOP

转载 作者:行者123 更新时间:2023-12-01 08:36:42 24 4
gpt4 key购买 nike

我正在尝试使用 Spring.Net for AOPlogging 添加到 用属性装饰的方法

第 1 步:引用“Spring.Core”、“Spring.Aop”、“Common.Logging”

第 2 步:创建建议:

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 步:创建属性:

using System;

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

第 4 步:编辑 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>

第 5 步:使用属性装饰方法:

using System.Web.Mvc;

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

建议从未触发。我错过了什么?

最佳答案

这与创建 Controller 然后实际调用它自己的 DoStuff() 的事实有关。 Controller 显然没有自己的代理,因此对 DoStuff() 的调用不会被 Spring.Net AOP 拦截。

正如 tobsen 在他的回答中提到的,您必须从 spring 中获取 Controller ,否则不会发生拦截。我假设您在这里使用 spring mvc 支持来创建 Controller ,但这并没有从您的问题中清楚地显示出来,您可能已经忽略了它。

如何拦截 MVC 3 Controller 上的操作方法

总结

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

  1. 使用 InheritanceBasedAopConfigurer
  2. 将要拦截的方法声明为虚拟方法
  3. 配置你的拦截器

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

当向 MVC 应用程序发出请求时,MVC 框架会从请求 url 中选择一个 Controller 。在此 Controller 上,调用 Execute() 方法,该方法又负责调用操作方法。重要的是要意识到 Action 方法总是从 Controller 内部调用

Spring.NET aop 使用动态编织。默认情况下,在运行时会为配置中声明了 aop 顾问的对象创建代理。该代理拦截调用并将调用转发到目标实例。这是在代理 interfaces 时完成的。和 classes (using proxy-target-type="true") .当目标对象调用它自己的方法时,它不会通过 spring 代理执行此操作,并且方法不会被拦截。这就是为什么默认的 aop 机制不适用于 mvc Controller 的原因。

...但是使用 InheritanceBasedAopConfigurer 可以解决问题

要拦截对操作方法的调用,您应该使用 InheritanceBasedAopConfigurer .这将创建一个不委托(delegate)给目标对象的基于继承的代理,而是在调用基类方法之前直接在方法体中添加拦截建议。

请注意,要使此拦截方法起作用,方法必须是虚拟的。

以下 xml 配置有效:

<!-- 
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>

一个有效的例子是available on github .它基于标准 mvc 3 应用程序,带有 Spring.Net Mvc3 support .相关文件有:

引用文献

关于.net - 使用 Spring.Net 的不显眼的 AOP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9114762/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com