Spring.NET.AOP - ExceptionHandlerAdvice 不会替换自定义异常

发布于 2024-12-17 00:01:28 字数 3701 浏览 1 评论 0原文

这是我的第一次,也是 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.ArgumentExceptionCustomerException

我不确定 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁人与我共长歌 2024-12-24 00:01:28

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 时,您必须将以下对象定义添加到您的配置中:

<object id="ExceptionAdvisorForSaveMethods" 
        type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
  <property name="advice" ref="exceptionHandlerAdvice"/>
  <property name="patterns">
    <list>
      <value>.*Save.*</value>
    </list>
  </property>
</object>

<object id="ProxyCreator" 
        type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop" />

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 a CustomerDao instance, but an aop proxy from Spring implementing the ICustomerDao interface. This proxy intercepts the call to Save(...) and applies your exception handling advice.

However, you haven't configured a ProxyFactory, so you will not get a proxy, but a CustomerDao instance when calling var customerDao = (ICustomerDao)context["customerDao"];. You can check this in the debugger; inspect the (runtime) type of customerDao.

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 plain ProxyFactoryObject or another AutoProxy.

When using an AdvisorAutoProxy, you have to add the following object definitions to your configuration:

<object id="ExceptionAdvisorForSaveMethods" 
        type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
  <property name="advice" ref="exceptionHandlerAdvice"/>
  <property name="patterns">
    <list>
      <value>.*Save.*</value>
    </list>
  </property>
</object>

<object id="ProxyCreator" 
        type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文