Asp.Net MVC 控制器:使用 Spring.Net 的声明式 AOP
Spring.Net 方面是否有可能无法与 Asp.Net 控制器一起使用?
我想在控制器的操作方法上配置事务,但代理似乎没有触发。
<object id="ControllerClassPointcut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
<property name="patterns">
<list>
<value>xxx.Controllers.CompanyController.*</value>
</list>
</property>
</object>
<aop:config>
<aop:advisor pointcut-ref="ControllerClassPointcut" advice-ref="TxAdvice"/>
<!-- TxAdvice taken from ServiceContext -->
</aop:config>
<tx:advice id="TxAdvice" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="*" propagation="Required"/>
</tx:attributes>
</tx:advice>
CompanyController 的操作方法是:
[HttpPost]
public virtual ActionResult Create(Guid id, CompanyonViewModel vm)
{
...
}
但我虽然识别了切入点,但建议并未生效。如果我采用控制器以外的其他类作为切入点,它就可以工作。
对于某些方法,该建议有效。例如存储库的设置器。但 Sprint.Net 无法识别调用了操作方法“Create”
候选是:'xxx.Controllers.CompanyController.set_CompanyService';模式是'xxx.Controllers.CompanyController.*';匹配=真 候选顾问 [DefaultObjectFactoryPointcutAdvisor: 切入点 [Spring.Aop.Support.SdkRegularExpressionMethodPointcut];建议对象 = 'TxAdvice'] 接受 targetType [xxx.Controllers.CompanyController]
感谢您的帮助
Is it possible, that Spring.Net Aspects don't work with Asp.Net Controller?
I want to configure transactions on Action methods of Controllers but the proxy doesn't seem to trigger.
<object id="ControllerClassPointcut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
<property name="patterns">
<list>
<value>xxx.Controllers.CompanyController.*</value>
</list>
</property>
</object>
<aop:config>
<aop:advisor pointcut-ref="ControllerClassPointcut" advice-ref="TxAdvice"/>
<!-- TxAdvice taken from ServiceContext -->
</aop:config>
<tx:advice id="TxAdvice" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="*" propagation="Required"/>
</tx:attributes>
</tx:advice>
and the action method of the CompanyController is:
[HttpPost]
public virtual ActionResult Create(Guid id, CompanyonViewModel vm)
{
...
}
but I the advice does not take effect although the pointcut is recognized. If I take an other class than a controller as pointcut it works.
for some methods the advice works. For example for the setter for the repository. But Sprint.Net does not recognize that the action method "Create" is called
Candidate is: 'xxx.Controllers.CompanyController.set_CompanyService'; pattern is 'xxx.Controllers.CompanyController.*'; matched=True
Candidate advisor [DefaultObjectFactoryPointcutAdvisor: pointcut [Spring.Aop.Support.SdkRegularExpressionMethodPointcut]; advice object = 'TxAdvice'] accepted for targetType [xxx.Controllers.CompanyController]
Thanks for your help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试使用配置
这将创建一个基于继承的代理。您可能需要下载 spirng.net 最近的每晚版本才能正常工作(不是 1.3.0)。
Can you try with the configuration
This will create an inheritance based proxy. you may need to download a recent nightly build of spirng.net for this to work (not 1.3.0).
我在
[Transaction]
属性(使用Spring.AOP
工作)方面遇到了类似的问题。就我而言,我从同一个类中调用了
[Transaction]
标记的方法,并对交易建议没有触发感到惊讶。解释是,当从类内调用
[Transaction]
标记方法时,您持有对真实实例而不是 AOP 代理实例的引用,因此该调用不会被拦截。当向 MVC 应用程序发出请求时,将从请求 URL 中选择一个控制器(从
IControllerFactory
实例)。在此控制器上,调用 Execute 方法,该方法又负责调用操作。所以我认为动作方法总是从控制器内部调用。这意味着根据定义,操作方法永远不会被拦截。这可以解释为什么这些切入点被识别但不触发。控制器之外的其他类上的切入点会触发:它们很可能是从控制器调用的,控制器将保存对其他类实例的 AOP 代理引用。
我假设您的(例如)
CompanyController.CustomerController
有一个属性CustomerRepository
,使用 DI 设置。触发此切入点是有道理的,因为 setter 是从 CompanyController.CustomerController 外部调用的,例如由 DI 容器(或 ControllerFactory)调用。解决方案可能是引入服务对象,您可以在服务对象上定义控制器上现在的事务建议。从控制器中,您可以调用这些服务对象上的方法,然后切入点将会触发。
I had a similar a problem with the
[Transaction]
attribute (which works usingSpring.AOP
).In my case, I called the
[Transaction]
flagged methods from within the same class and was surprised that the transaction advice didn't fire.The explanation was, that when calling a
[Transaction]
marked method from within the class, you hold a reference to the real instance instead of the AOP-proxied instance, therefore the call does not get intercepted.When a request is made to an MVC app, then from the request url a controller is chosen (from the
IControllerFactory
instance). On this controller, theExecute
method is called, which in turn is responsible for calling the actions. So I think that action methods are always called from within the controller. Which means that by definition action methods will never get intercepted. This would explain why those pointcuts are recognized, but don't fire.It also explains why pointcuts on other classes than controllers do fire: they are likely called from a controller, which will hold a AOP-proxied reference to instances of the other classes.
I assume that your (for instance)
CompanyController.CustomerController
has a propertyCustomerRepository
, set using DI. It makes sense that this pointcut fires, because the setter is called from outside theCompanyController.CustomerController
, for instance by your DI container (or yourControllerFactory
).A solution could be to introduce service objects, on which you define the transaction advice that you now have on your controllers. From your controllers, you call methods on these service objects - and then the pointcuts will fire.