Dav*_*vid 3 .net asp.net-mvc spring.net spring-aop
我尝试添加记录,以饰有一个属性的方法使用Spring.Net AOP的.
第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
}
}
}
Run Code Online (Sandbox Code Playgroud)
第3步:创建属性:
using System;
namespace MyApp.Aspects
{
public class LoggingAttribute : Attribute
{
}
}
Run Code Online (Sandbox Code Playgroud)
第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>
Run Code Online (Sandbox Code Playgroud)
第5步:使用属性装饰方法:
using System.Web.Mvc;
namespace MyApp.Controllers
{
public class MyController : Controller
{
[Logging]
public ActionResult DoStuff()
{
//todo: implement
}
}
}
Run Code Online (Sandbox Code Playgroud)
该建议是永远不会触发.我错过了什么?
这与创建控制器然后实际调用DoStuff()它的事实有关.控制器显然没有自己的代理,因此调用DoStuff()不会被Spring.Net AOP截获.
正如托克森在他的回答中提到的那样,你必须从春天开始接收控制器,否则就不会发生拦截.我假设您在这里使用spring mvc支持来创建控制器,但是这并没有从您的问题中清楚地显示出来并且您可能已将其删除.
摘要
请参阅下面的详细信息和示例.
InheritanceBasedAopConfigurerSpring的默认拦截机制不起作用......
当向MVC应用程序发出请求时,则从请求URL开始,MVC框架选择控制器.在此控制器上,Execute()调用该方法,该方法又负责调用操作方法.重要的是要意识到始终从控制器内调用操作方法.
Spring.NET aop使用动态编织.默认情况下,在运行时,会为在配置中声明了aop顾问程序的对象创建代理.此代理拦截调用并转发对目标实例的调用.代理接口和类(使用proxy-target-type="true")时完成此操作.当目标对象在其上调用一个方法时,它不会通过spring代理执行此操作,并且该方法不会被截获.这就是为什么默认的aop机制不适用于mvc控制器.
......但使用一个InheritanceBasedAopConfigurer诀窍
要拦截对操作方法的调用,您应该使用InheritanceBasedAopConfigurer.这将创建一个基于继承的代理,该代理不会委托给目标对象,而是在调用基类方法之前直接在方法体中添加拦截建议.
请注意,要使此拦截方法起作用,方法必须是虚拟的.
以下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>
Run Code Online (Sandbox Code Playgroud)
github上有一个工作示例.它基于支持Spring.Net Mvc3的标准mvc 3应用程序.相关文件是:
参考
DoStuff()应该声明为虚拟.| 归档时间: |
|
| 查看次数: |
2739 次 |
| 最近记录: |