Spring.NET.AOP - ExceptionHandlerAdvice 不会替换自定义异常
这是我的第一次,也是 Spring.NET 和 AOP 的初学者。
我想使用 Aspect for Exception Hadling 来替换、包装和修改我的自定义异常。
首先我定义了一些实体和 DAO。从 DAO 中的 Save 方法中,我将抛出异常。
仅供参考:这是愚蠢的示例
Entity:
namespace ExceptionHandlingTutorial.Entities
{
public class Customer
{
public long Id { get; set; }
public string Name { get; set; }
}
}
DAO:
namespace ExceptionHandlingTutorial.Dao
{
public interface ICustomerDao
{
void Save(Customer customer);
}
public class CustomerDao:ICustomerDao
{
#region Implementation of ICustomerDao
public void Save(Customer customer)
{
throw new CustomerException(
string.Format("Customer with id {0} already exist in repository",customer.Id));
}
#endregion
}
}
CustomException 类定义在这里:
namespace ExceptionHandlingTutorial
{
public class CustomerException : Exception
{
public CustomerException(string msg)
: base(msg)
{
}
}
}
在 app.config 中我定义了 CustomerDao
对象和 ExceptionHandlerAdvice
对象,仅替换 System.ArgumentException
的 CustomerException
。
我不确定 ExceptionHandlerAdvice 是否是自动代理,也不知道它如何识别目标。
我相信它使用 SpEL 来定义规则,当出现一些异常时它会抛出检查列表。 好的,这种类型的例外情况已在列表中,我将应用建议。
有人可以向我解释一下这方面如何确定目标吗?例如,我只想将此方面应用于少数对象而不是全部。
我使用参考文档第 14.3 章异常处理,但我找不到这些信息。
这里是 app.config:
<?xml version="1.0" encoding="utf-8" ?>
<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.springframework.net">
<object id="customerDao"
type="ExceptionHandlingTutorial.Dao.CustomerDao, ExceptionHandlingTutorial"/>
<object id="exceptionHandlerAdvice"
type="Spring.Aspects.Exceptions.ExceptionHandlerAdvice, Spring.Aop">
<property name="ExceptionHandlers">
<list>
<value>on exception name CustomerException replace System.ArgumentException 'Something'</value>
</list>
</property>
</object>
</objects>
</spring>
</configuration>
我的主要问题是,如果我在 DAO 上调用 Save 方法,它会抛出 CustomerException 异常类型,此异常不会被替换。为什么?
try
{
var context = ContextRegistry.GetContext();
var customerDao = (ICustomerDao)context["customerDao"];
customerDao.Save(new Customer { Id = 1, Name = "Customer_1" });
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception type: {0}\nException message: {1}\n",
ex.GetType(),ex.Message));
}
抛出的异常是 CustomerException
类型,而不是 ArgumentException
,
我还尝试在应用建议时使用 DSL 来定义规则:
on exception (#e is T(ExceptionHandlingTutorial.CustomerException) translate new System.ArgumentException('XChange, Method Name'+ #method.Name, #e))
但仍然是抛出 CustomerException 异常类型。
谢谢你的帮助。
this is my first and also I am beginner in Spring.NET and also AOP.
I would like use Aspect for Exception Hadling for replacing, wrap and modify my custom exceptions.
First I defined some entity and DAO. From method Save in DAO I will throw my exception.
FYI: This is silly sample
Entity:
namespace ExceptionHandlingTutorial.Entities
{
public class Customer
{
public long Id { get; set; }
public string Name { get; set; }
}
}
DAO:
namespace ExceptionHandlingTutorial.Dao
{
public interface ICustomerDao
{
void Save(Customer customer);
}
public class CustomerDao:ICustomerDao
{
#region Implementation of ICustomerDao
public void Save(Customer customer)
{
throw new CustomerException(
string.Format("Customer with id {0} already exist in repository",customer.Id));
}
#endregion
}
}
CustomException class definition is here:
namespace ExceptionHandlingTutorial
{
public class CustomerException : Exception
{
public CustomerException(string msg)
: base(msg)
{
}
}
}
In app.config I defined CustomerDao
object and ExceptionHandlerAdvice
object which only replace CustomerException
for System.ArgumentException
.
I am not sure if ExceptionHandlerAdvice
is auto-proxy and also I don’t how it identified targets.
I believe that it uses SpEL for define rules and when there is some exception it throws check list.
Ok this type of exception is in list some I will apply advice.
Can anybody explain to me how this aspect identified targets? For example I would like apply this aspect only for a few objects not all.
I use ref documentation Chapter 14.3 Exception handling but I couldnt find these information.
Here is app.config:
<?xml version="1.0" encoding="utf-8" ?>
<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.springframework.net">
<object id="customerDao"
type="ExceptionHandlingTutorial.Dao.CustomerDao, ExceptionHandlingTutorial"/>
<object id="exceptionHandlerAdvice"
type="Spring.Aspects.Exceptions.ExceptionHandlerAdvice, Spring.Aop">
<property name="ExceptionHandlers">
<list>
<value>on exception name CustomerException replace System.ArgumentException 'Something'</value>
</list>
</property>
</object>
</objects>
</spring>
</configuration>
My main problem is that if I call method Save on DAO it throw exception type of CustomerException this exception is not replaced. Why?
try
{
var context = ContextRegistry.GetContext();
var customerDao = (ICustomerDao)context["customerDao"];
customerDao.Save(new Customer { Id = 1, Name = "Customer_1" });
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception type: {0}\nException message: {1}\n",
ex.GetType(),ex.Message));
}
Thrown exception is type of CustomerException
not ArgumentException
,
Also I tried use DSL for defined rules when advice apply:
on exception (#e is T(ExceptionHandlingTutorial.CustomerException) translate new System.ArgumentException('XChange, Method Name'+ #method.Name, #e))
But still is throw exception type of CustomerException.
Thank you for help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Spring.NET aop 动态地为您想要应用建议的对象创建代理。当您执行
var customerDao = (ICustomerDao)context["customerDao"];
时,Spring.NET 返回此代理。因此,当配置正确时,您不会获得CustomerDao
实例,而是获得来自 Spring 的实现ICustomerDao
接口的 aop 代理。该代理拦截对Save(...)
的调用并应用您的异常处理建议。但是,您尚未配置
ProxyFactory
,因此在调用var customerDao = (ICustomerDao)context[" 时,您不会获得代理,而是获得
。您可以在调试器中检查这一点;检查CustomerDao
实例customerDao"];customerDao
的(运行时)类型。配置代理工厂有多种方法;我建议您使用
AdvisorAutoProxy< /code>
对于您的情况,但您也可以使用普通的
ProxyFactoryObject
或其他 < a href="http://www.springframework.net/doc-latest/reference/html/aop.html#aop-autoproxy" rel="nofollow">AutoProxy
。使用
AdvisorAutoProxy
时,您必须将以下对象定义添加到您的配置中:Spring.NET aop dynamically creates a proxy for the objects you want to apply advice to. Spring.NET returns this proxy when you do
var customerDao = (ICustomerDao)context["customerDao"];
. So when configured correctly, you don't get aCustomerDao
instance, but an aop proxy from Spring implementing theICustomerDao
interface. This proxy intercepts the call toSave(...)
and applies your exception handling advice.However, you haven't configured a
ProxyFactory
, so you will not get a proxy, but aCustomerDao
instance when callingvar customerDao = (ICustomerDao)context["customerDao"];
. You can check this in the debugger; inspect the (runtime) type ofcustomerDao
.There are several methods to configure the proxy factory; I'd advise you to use an
AdvisorAutoProxy
for your case, but you can also configure it manually for each object using a plainProxyFactoryObject
or anotherAutoProxy
.When using an
AdvisorAutoProxy
, you have to add the following object definitions to your configuration: