【问题标题】:Spring.NET.AOP - ExceptionHandlerAdvice doesnt replace custom exceptionSpring.NET.AOP - ExceptionHandler Advice 不替换自定义异常
【发布时间】:2011-11-17 23:54:11
【问题描述】:

这是我的第一个,也是 Spring.NET 和 AOP 的初学者。

我想使用 Aspect for Exception Hadling 来替换、包装和修改我的自定义异常。

首先我定义了一些实体和 DAO。从 DAO 中的方法 Save 我将抛出我的异常。

仅供参考:这是愚蠢的示例

实体:

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 对象,它们仅将 CustomerException 替换为 System.ArgumentException

我不确定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。

感谢您的帮助。

【问题讨论】:

    标签: exception-handling spring.net aop


    【解决方案1】:

    Spring.NET aop 为您想要应用建议的对象动态创建一个代理。当您执行var customerDao = (ICustomerDao)context["customerDao"]; 时,Spring.NET 会返回此代理。所以如果配置正确,你不会得到CustomerDao 实例,而是来自Spring 的aop 代理,它实现了ICustomerDao 接口。此代理拦截对Save(...) 的调用并应用您的异常处理建议。

    但是,您还没有配置ProxyFactory,因此在调用var customerDao = (ICustomerDao)context["customerDao"]; 时,您不会得到一个代理,而是一个CustomerDao 实例。您可以在调试器中检查这一点;检查customerDao的(运行时)类型。

    代理工厂有几种配置方法;我建议您针对您的情况使用 AdvisorAutoProxy,但您也可以使用普通的 ProxyFactoryObject 或另一个 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" />
    

    【讨论】:

    • 感谢您的精彩解释。现在对我来说显然是 :) 我刚刚创建了基于类型名称的自动代理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 2019-11-23
    • 2018-10-18
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多