Я начинаю изучать среду Spring.NET, и меня очень смущает поведение прокси, авто-прокси и обработки исключений.
например, я определил простой бизнес-объект, и из этого объекта я сгенерирую пользовательское исключение.
namespace Aspect.Managers
{
public interface IDbCustomerManager
{
Customer GetCustomerById(long id);
}
public class DbCustomerManager:IDbCustomerManager
{
public Customer GetCustomerById(long id)
{
throw new DbException(string.Format("Problem load customer with Id: {0}",id));
}
}
}
Во-вторых, я определил Advice для обработки исключений.
public class LogExThrowsAdvice:IThrowsAdvice
{
public void AfterThrowing(MethodInfo method, Object[] args,
Object target, DbException exception)
{
Console.WriteLine(exception.Message);
}
}
И, наконец, я присоединяюсь к бизнес-объекту togheter и совету с прокси.
В app.confing
Совет:
<object id="theLogExThrowsAdvice"
type="Aspect.LogExThrowsAdvice, Log4NetInSpringNet"/>
Авто-прокси
<object id="theProxyCreator"
type="Spring.Aop.Framework.AutoProxy.TypeNameAutoProxyCreator, Spring.Aop">
<property name="TypeNames" value="Aspect.Managers.DbCustomerManager*"/>
<property name="InterceptorNames">
<list>
<value>theLogExThrowsAdvice</value>
</list>
</property>
</object>
И проверить это:
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theDbCustomerManager"];
dbMgr.GetCustomerById(1);
Исключение выдается, метод AfterThrowing из LogExThrowsAdvice не вызывается.
Я пытаюсь изменить тип рекомендации для типа BeforeAdvice.
public class DbAccessAdvice:IMethodBeforeAdvice
{
#region Implementation of IMethodBeforeAdvice
public void Before(MethodInfo method, object[] args, object target)
{
Console.WriteLine("You try access to DB");
}
#endregion
}
и в app.config:
<object id="theDbAccessAdvice"
type="Aspect.DbAccessAdvice, Log4NetInSpringNet"/>
<object id="theProxyCreator"
type="Spring.Aop.Framework.AutoProxy.TypeNameAutoProxyCreator, Spring.Aop">
<property name="TypeNames" value="Aspect.Managers.DbCustomerManager*"/>
<property name="InterceptorNames">
<list>
<value>theDbAccessAdvice</value>
<value>theLogExThrowsAdvice</value>
</list>
</property>
</object>
BeforeAdvice это огонь, а ThrowsAdvice нет. Почему?
Я попытался изменить автоматический прокси для фабрики прокси-объектов и попытался проксировать интерфейсы IDbCustomerManager.
<object id="theProxy"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="ProxyInterfaces" value="Aspect.Managers.IDbCustomerManager"/>
<property name="Target">
<object type="Aspect.Managers.DbCustomerManager">
</object>
</property>
<property name="InterceptorNames">
<list>
<value>theDbAccessAdvice</value>
<value>theLogAdvice</value>
</list>
</property>
</object>
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theProxy"];
dbMgr.GetCustomerById(1);
До того, как совет уволен, но не бросает совет? Зачем? Выдается только исключение.
Для меня это магия, как это действительно работает.
Я попробовал использовать советники вместо советов:
<!--Advisor-->
<object id="theDbAccessAdvisor"
type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="Pattern" value="Aspect*"/>
<property name="Advice" ref="theDbAccessAdvice"/>
</object>
<object id="theLogAdvisor"
type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="Pattern" value="Aspect*"/>
<property name="Advice" ref="theLogAdvice"/>
</object>
Но тот же результат до того, как совет уволен, но не выдает совет.
Я пытался использовать также аспект ExceptionHandleAdvice из Spring.NET, выдается то же исключение, но не совет.
<object id="exAdvice"
type="Spring.Aspects.Exceptions.ExceptionHandlerAdvice, Spring.Aop">
<property name="ExceptionHandlers">
<list>
<value>on exception name DbException swallow</value>
</list>
</property>
</object>
Этот проект для меня волшебство. Я загружаю все проекты VS здесь:
http://hotfile.com/dl/135485464/93558e0/Log4Net.7z.html
Вот стек исключений:
в Aspect.Managers.DbCustomerManager.GetCustomerById (Int64 id) в
E: \ C #
ПРОЕКТЫ \ ИССЛЕДОВАНИЯ \ SPRING.NET \ Study.Spring.Net \ Аспекты \ Logging \ Log4Net \ Менеджеры \ DbCustomerManager.cs: линия
20 в
_dynamic_Aspect.Managers.DbCustomerManager.GetCustomerById (Object, Object []) в Spring.Reflection.Dynamic.SafeMethod.Invoke (Object
target, Object [] arguments) в
Spring.Aop.Framework.DynamicMethodInvocation.InvokeJoinpoint () в
Spring.Aop.Framework.AbstractMethodInvocation.Proceed () в
Spring.Aspects.Exceptions.ExceptionHandlerAdvice.Invoke (IMethodInvocation
вызов)
Также, если я попытаюсь поймать исключение примерно так:
try
{
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theDbCustomerManager"];
dbMgr.GetCustomerById(1);
}
catch (Exception ex)
{
Console.WriteLine("{0}\n{1}", ex.GetType(), ex.Message);
}
Это невозможно ... системное сообщение об ошибке является необработанным исключением ....