我正在学习Spring.Net,我正在尝试一些简单的东西,但是没有用。我想记录用LogCall
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
Test();
InitializeComponent();
}
[LogCall]
public void Test()
{
}
}
public class LogCallInterceptor : IMethodBeforeAdvice
{
public void Before(MethodInfo method, object[] args, object target)
{
Debug.Write(method.Name);
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class LogCallAttribute : Attribute
{
}
}
这是App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<spring>
<objects xmlns="http://www.springframework.net">
<object id="TestLogAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
<property name="advice">
<object type="WpfApplication1.LogCallInterceptor, WpfApplication1" />
</property>
<property name="attribute" value="WpfApplication1.LogCallAttribute, WpfApplication1" />
</object>
</objects>
</spring>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Spring.Core" publicKeyToken="65e474d141e25e07" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.2.40943" newVersion="1.3.2.40943" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Spring.Aop" publicKeyToken="65e474d141e25e07" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.2.40943" newVersion="1.3.2.40943" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
我对这一切都很陌生,所以我甚至不确定这是否是一种有效的方法。
根据第一个答案,我重复了我的例子。还是行不通?我变暖了吗?
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
var someClass = new SomeClass();
someClass.Test();
InitializeComponent();
}
}
public class SomeClass
{
[LogCall]
public void Test()
{
}
}
public class LogCallInterceptor : IMethodBeforeAdvice
{
public void Before(MethodInfo method, object[] args, object target)
{
Debug.Write(method.Name);
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class LogCallAttribute : Attribute
{
}
}
新的app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<spring>
<objects xmlns="http://www.springframework.net">
<object id="TestLogAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
<property name="advice">
<object type="WpfApplication1.LogCallInterceptor, WpfApplication1" />
</property>
<property name="attribute" value="WpfApplication1.LogCallAttribute, WpfApplication1" />
</object>
</objects>
<object id="mySomeClass" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySomeClassTarget" type="WpfApplication1.SomeClass"/>
</property>
<property name="interceptorNames">
<list>
<value>TestLogAdvice</value>
</list>
</property>
</object>
</spring>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Spring.Core" publicKeyToken="65e474d141e25e07" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.2.40943" newVersion="1.3.2.40943" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Spring.Aop" publicKeyToken="65e474d141e25e07" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.2.40943" newVersion="1.3.2.40943" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
答案 0 :(得分:3)
您正在使用spring aop来设置日志记录,这是一种有效的方法。有几件事你需要考虑:
Spring AOP使用动态代理来装饰具有(日志记录)建议的类。此代理拦截对您的对象的调用并应用日志记录建议。在您的课程中,您可以在类中调用Test
方法。这样,动态代理永远不会拦截调用,也不会进行日志记录。
从您的配置中我读到您定义了哪些建议必须运行(您的LogCallInterceptor
)和哪里(与您的属性匹配的方法),但我看不到您定义代理工厂的位置。 Spring必须创建一个代理,你必须告诉它在哪里做。
aop quickstart是了解如何执行此操作的好地方。实际上,第一个示例之一是日志示例,它非常适用于您的问题。我猜测在阅读快速入门的第一部分(第38.2.1章)之后,你会知道如何使其发挥作用。
Spring AOP是一种强大的技术,但最初可能有点难以掌握。你已经顺利了。
编辑1
我看到你已经更新了你的问题。我想,你几乎就在那里。
现在,您正在直接从代码创建SomeClass
实例。这样,Spring再次没有机会创建它的代理。您必须委派SomeClass
的创建
到弹簧容器:
public MainWindow()
{
// normally speaking, we should not create the container here,
// but that's another subject
var ctx = ContexRegistry.GetContext(); // init spring container
var someClass = (SomeClass) ctx["mySomeClass"];
someClass.Test();
InitializeComponent();
}
这样,someClass
将保留代理而不是目标。
此后,还有一个问题(hint)。
编辑2
您的Test
方法必须是虚拟的,否则spring无法创建基于继承的代理。 (或者你的类必须实现一个或多个接口)。
使用自动代理配置
以下app.config使用DefaultAdvisorAutoProxyCreator
。这将确保您不必为要应用日志记录顾问程序的每个类创建代理工厂。 DefaultAdvisorAutoProxyCreator
会找到LogCallAttribute
的所有对象并为其创建代理。
<?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="TestLogAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
<property name="advice">
<object type="q8029460.LogCallInterceptor, q8029460" />
</property>
<property name="attribute" value="q8029460.LogCallAttribute, q8029460" />
</object>
<object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>
<object id="mySomeClass" type="q8029460.MyClass, q8029460" />
</objects>
</spring>
</configuration>