Spring.net Logging Example Using aop

I am studying Spring.Net and trying something simple that doesn't work. I want to register any method calls decorated with 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 { } } 

And here is 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> 

I'm really new to this, so I'm not even sure if this is a valid approach.

Based on the first answer, I reworked my example. Still not working? Will I keep warm?

 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 { } } 

And the new 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> 
+1
source share
1 answer

You use spring aop to configure logging, and this is a valid approach. There are a few things you should consider:

Spring AOP uses a dynamic proxy to decorate the class with (logging) tips. This proxy server intercepts calls to your object and applies a registration tip. In your class, you call the Test method from the class itself. Thus, a dynamic proxy server will never be able to intercept the call, and no protocols will happen.

I read from your config that you determine what advice you need to execute (your LogCallInterceptor ) and where (the methods match your attribute), but I don’t see where you define your factory proxy. spring should create a proxy, and you should tell it where to do it.

aop quickstart is a good place to learn how to do it. In fact, one of the first examples is the registration example, which is very applicable to your question. I assume that after reading the first part of the quick start (chapter 38.2.1.), You will understand what to do to make this work.

Spring AOP is a powerful technique, but at first it can be a bit of a challenge. You are already on the way.

Change 1

I see that you have updated your question. I think you're almost there.

Now you instantiate SomeClass directly from the code. This way, spring will not get the opportunity to create its proxy again. You must delegate the creation of SomeClass to the spring container:

 public MainWindow() { // normally speaking, we should not create the container here, // but that another subject var ctx = ContexRegistry.GetContext(); // init spring container var someClass = (SomeClass) ctx["mySomeClass"]; someClass.Test(); InitializeComponent(); } 

Thus, SomeClass will hold the proxy instead of the target.

After this, one problem remains ( hint ).

Edit 2

Your Test method must be virtual, otherwise spring cannot create a proxy based on inheritance. (or your class must implement one or more interfaces).

Auto Proxy Configuration

The following app.config application uses DefaultAdvisorAutoProxyCreator . This ensures that you do not need to create a proxy factory for each class to which you want to apply a logging advisor. DefaultAdvisorAutoProxyCreator will find all objects with LogCallAttribute and create a proxy for them.

 <?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> 
+3
source

Source: https://habr.com/ru/post/901741/


All Articles