{"id":541,"date":"2012-01-01T23:28:33","date_gmt":"2012-01-01T22:28:33","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=541"},"modified":"2012-01-01T23:28:33","modified_gmt":"2012-01-01T22:28:33","slug":"advanced-aspectj-part-v-integration-with-spring","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=541","title":{"rendered":"Advanced AspectJ part V : integration with Spring"},"content":{"rendered":"<p>In this article we&#8217;ll see how to integrate your own aspects with Spring.<\/p>\n<p>First we focus on load-time weaving using Spring&#8217;s dedicated AspectJ agents. Then we&#8217;ll see how to let Spring inject beans into your aspects<\/p>\n<p><!--more--><\/p>\n<blockquote><p>The below configuration is valid for <strong>Spring 3.0.5<\/strong>, <strong>Tomcat 6<\/strong> &amp; <strong>AspectJ 1.6.12<\/strong><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>I Load-time weaving with Spring<\/h1>\n<h2>A Spring configuration<\/h2>\n<p>To enable load-time weaving, we must add the <strong>&lt;context:load-time-weaver&gt;<\/strong> tag in the Spring XML configuration<\/p>\n<pre class=\"brush: xml; highlight: [9,10,11]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;\n&amp;lt;beans xmlns=&amp;quot;http:\/\/www.springframework.org\/schema\/beans&amp;quot;\n\txmlns:xsi=&amp;quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&amp;quot;\n\txmlns:context=&amp;quot;http:\/\/www.springframework.org\/schema\/context&amp;quot;\n\txsi:schemaLocation=&amp;quot;http:\/\/www.springframework.org\/schema\/beans http:\/\/www.springframework.org schema\/beans\/spring-beans-3.0.xsd\n\thttp:\/\/www.springframework.org\/schema\/context http:\/\/www.springframework.org\/schema\/context\/spring-context-2.5.xsd&amp;quot;&amp;gt;\n\t...\n\t...\n\t&amp;lt;context:load-time-weaver \n\t\tweaver-class=&amp;quot;org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver&amp;quot;\n\t\taspectj-weaving=&amp;quot;on&amp;quot;\/&amp;gt;\n\t...\n\t...\n&amp;lt;\/beans&amp;gt;\n<\/pre>\n<p>The weaver class <strong>org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver<\/strong> is applicable to Tomcat 6. If you are using another application server or servlet container, please refer to Spring official recommendation (table 7.1) here : <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.0.5.RELEASE\/spring-framework-reference\/html\/aop.html#aop-aj-ltw-spring\" title=\"Weaver Class\" target=\"_blank\">Weaver Class configuration<\/a><\/p>\n<p>You need to add extra Maven dependencies to your project&#8217; <strong>pom.xml<\/strong> to get this class:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n\t&amp;lt;dependency&amp;gt;\n  \t\t&amp;lt;groupId&amp;gt;org.springframework&amp;lt;\/groupId&amp;gt;\n  \t\t&amp;lt;artifactId&amp;gt;spring-instrument&amp;lt;\/artifactId&amp;gt;\n  \t\t&amp;lt;version&amp;gt;3.0.5.RELEASE&amp;lt;\/version&amp;gt;\n  \t\t&amp;lt;type&amp;gt;jar&amp;lt;\/type&amp;gt;\n  \t\t&amp;lt;scope&amp;gt;compile&amp;lt;\/scope&amp;gt;\n  \t&amp;lt;\/dependency&amp;gt;\n\t&amp;lt;dependency&amp;gt;\n  \t\t&amp;lt;groupId&amp;gt;org.springframework&amp;lt;\/groupId&amp;gt;\n  \t\t&amp;lt;artifactId&amp;gt;spring-aspects&amp;lt;\/artifactId&amp;gt;\n  \t\t&amp;lt;version&amp;gt;3.0.5.RELEASE&amp;lt;\/version&amp;gt;\n  \t\t&amp;lt;type&amp;gt;jar&amp;lt;\/type&amp;gt;\n  \t\t&amp;lt;scope&amp;gt;compile&amp;lt;\/scope&amp;gt;\n  \t&amp;lt;\/dependency&amp;gt;\n<\/pre>\n<p><strong>spring-instrument-3.0.5.RELEASE.jar<\/strong> contains an Instrumentation agent needed at runtime and <strong>spring-aspects-3.0.5.RELEASE.jar<\/strong> contains aspects for Spring&#8217;s:<\/p>\n<ul>\n<li><strong>@Transactional<\/strong> support<\/li>\n<li><strong>@Configurable<\/strong> support<\/li>\n<li>JPA Exception translation support<\/li>\n<li><strong>@Async<\/strong> annotation for scheduling support<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>B Tomcat configuration<\/h2>\n<p>Spring is shipped with a special AspectJ agent dedicated to Tomcat server. First you need to download the jar by adding this Maven dependency:<\/p>\n<pre class=\"brush: xml; highlight: [3]; title: ; wrap-lines: false; notranslate\" title=\"\">\n\t&amp;lt;dependency&amp;gt;\n  \t\t&amp;lt;groupId&amp;gt;org.springframework&amp;lt;\/groupId&amp;gt;\n  \t\t&amp;lt;artifactId&amp;gt;spring-instrument-tomcat&amp;lt;\/artifactId&amp;gt;\n  \t\t&amp;lt;version&amp;gt;3.0.5.RELEASE&amp;lt;\/version&amp;gt;\n  \t\t&amp;lt;type&amp;gt;jar&amp;lt;\/type&amp;gt;\n  \t\t&amp;lt;scope&amp;gt;compile&amp;lt;\/scope&amp;gt;\n  \t&amp;lt;\/dependency&amp;gt;\n<\/pre>\n<p>Then put the <strong>spring-instrument-tomcat-3.0.5.RELEASE.jar<\/strong> file in the <em>&lt;Tomcat_Install&gt;\/lib<\/em> folder.<\/p>\n<p>Last but not least, add a custom class loader in Tomcat&#8217; configuration for your web app:<\/p>\n<pre class=\"brush: xml; highlight: [4]; title: ; wrap-lines: false; notranslate\" title=\"\">\n      \t &amp;lt;Context docBase=&amp;quot;myAspectJApp&amp;quot; \n      \t       \t path=&amp;quot;\/myAspectJApp&amp;quot; reloadable=&amp;quot;true&amp;quot;\n      \t       \t source=&amp;quot;org.eclipse.jst.jee.server:myAspectJApp&amp;quot;&amp;gt;\n      \t       \t &amp;lt;Loader loaderClass=&amp;quot;org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader&amp;quot;\/&amp;gt;\n      \t &amp;lt;\/Context&amp;gt;\n<\/pre>\n<p>There is still one last configuration step to go.<br \/>\n&nbsp;<\/p>\n<h2>C <em>aop.xml<\/em><\/h2>\n<p>You need to create an <strong>aop.xml<\/strong> file and at it to the <em>META-INF<\/em> folder of your web app.<\/p>\n<p>A sample <strong>aop.xml<\/strong> file:<\/p>\n<pre class=\"brush: xml; highlight: [4,8,9]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;!DOCTYPE aspectj PUBLIC &amp;quot;-\/\/AspectJ\/\/DTD\/\/EN&amp;quot; &amp;quot;http:\/\/www.eclipse.org\/aspectj\/dtd\/aspectj.dtd&amp;quot;&amp;gt;\n&amp;lt;aspectj&amp;gt;\n    &amp;lt;weaver options=&amp;quot;-verbose -showWeaveInfo -Xreweavable&amp;quot;&amp;gt;\n\t\t&amp;lt;include within=&amp;quot;com.myApp..*&amp;quot;\/&amp;gt;\n    &amp;lt;\/weaver&amp;gt;\n\n    &amp;lt;aspects&amp;gt;\n\t\t&amp;lt;concrete-aspect name=&amp;quot;com.myApp.aspect.AspectPrecedence&amp;quot;\nprecedence=&amp;quot;com.myApp.aspect.metric.MetricsAspect,com.myApp.aspect.exception.ExceptionCatcherAspect&amp;quot; \/&amp;gt;\n\t\t\t\t\n\t\t&amp;lt;aspect name=&amp;quot;com.myApp.aspect.metric.MetricsAspect&amp;quot;\/&amp;gt;\n\t\t&amp;lt;aspect name=&amp;quot;com.myApp.aspect.exception.ExceptionCatcherAspect&amp;quot;\/&amp;gt;\n    &amp;lt;\/aspects&amp;gt;\n\n  &amp;lt;\/aspectj&amp;gt;\n<\/pre>\n<p>Inside the <strong>&lt;weaver&gt;<\/strong> tag we declare all <strong>target classes to be woven with aspects by AspectJ<\/strong>. In the example, we restrict the classes to our application package to avoid AspectJ runtime to scan all classes on the classpath (very slow).<\/p>\n<p>Inside the <strong>&lt;aspects&gt;<\/strong> tag we list all the aspects needed for the weaving process. You can also declare a concrete aspect to manage aspect precedence at this place.<\/p>\n<p>You need not declare in the <strong>&lt;aspects&gt;<\/strong> section all Spring standard aspects (for @Transactional, @Configurable&#8230;). They are already declared in another <em>aop.xml<\/em> file in the <strong>spring-aspects-3.0.5.RELEASE.jar<\/strong><\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;\n&amp;lt;!--\n\tAspectJ load-time weaving config file to install common Spring aspects.\n--&amp;gt;\n&amp;lt;aspectj&amp;gt;\n\n\t&amp;lt;!--\n\t&amp;lt;weaver options=&amp;quot;-showWeaveInfo&amp;quot;\/&amp;gt;\n\t--&amp;gt;\n\n\t&amp;lt;aspects&amp;gt;\n\t\t&amp;lt;aspect name=&amp;quot;org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect&amp;quot;\/&amp;gt;\n\t\t&amp;lt;aspect name=&amp;quot;org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect&amp;quot;\/&amp;gt;\n\t\t&amp;lt;aspect name=&amp;quot;org.springframework.transaction.aspectj.AnnotationTransactionAspect&amp;quot;\/&amp;gt;\n\t&amp;lt;\/aspects&amp;gt;\n\n&amp;lt;\/aspectj&amp;gt;\n<\/pre>\n<p>&nbsp;<\/p>\n<h1>II Spring&#8217; aspects integration<\/h1>\n<p> To perform some business logic, your aspects may need to get a reference to a Spring managed bean. For this we can rely on dependency injection. However since the aspect instanciation and lifecycle is not managed by Spring but by AspectJ runtime, how can dependency be injected ?<\/p>\n<p> The <strong>aspectOf()<\/strong> method comes to the rescue. Refer to <a href=\"http:\/\/doanduyhai.wordpress.com\/2011\/12\/05\/advanced-aspectj-part-i-instanciation-model\/\" title=\"http:\/\/doanduyhai.wordpress.com\/2011\/12\/05\/advanced-aspectj-part-i-instanciation-model\/\" target=\"_blank\">Advanced AspectJ Part I : Instanciation model, chapter II Accessing the instance<\/a> for more details on it.<\/p>\n<p>By calling <strong>aspectOf()<\/strong> we can get the reference of the aspect instance. Dependency injection can be achieved by passing this instance to Spring.<\/p>\n<pre class=\"brush: xml; highlight: [1]; title: ; wrap-lines: false; notranslate\" title=\"\">\n\t&amp;lt;bean class=&amp;quot;com.myApp.aspect.metric.MetricsAspect&amp;quot; factory-method=&amp;quot;aspectOf&amp;quot;&amp;gt;\n\t\t&amp;lt;property name=&amp;quot;myDao&amp;quot; ref=&amp;quot;myDao&amp;quot;\/&amp;gt;\n\t\t&amp;lt;property name=&amp;quot;myEntityManagerFactory&amp;quot; ref=&amp;quot;myEntityManagerFactory&amp;quot;\/&amp;gt;\n\t&amp;lt;\/bean&amp;gt;\t\t\n<\/pre>\n<p>Of course <strong>this trick only works for aspect with singleton instanciation model<\/strong>. The other instanciation models need the target object as argument for <strong>aspectOf()<\/strong> (perthis, pertaget instanciations) or the control flow context (percflow, percflowbelow instantiations).<\/p>\n<p>If your aspects are advising the same join points as Spring standard aspects (@Transactional for example) you can change your aspect precedence against Spring&#8217; one.<\/p>\n<pre class=\"brush: xml; highlight: [8,9]; title: ; wrap-lines: false; notranslate\" title=\"\">\n&amp;lt;!DOCTYPE aspectj PUBLIC &amp;quot;-\/\/AspectJ\/\/DTD\/\/EN&amp;quot; &amp;quot;http:\/\/www.eclipse.org\/aspectj\/dtd\/aspectj.dtd&amp;quot;&amp;gt;\n&amp;lt;aspectj&amp;gt;\n    &amp;lt;weaver options=&amp;quot;-verbose -showWeaveInfo -Xreweavable&amp;quot;&amp;gt;\n\t\t&amp;lt;include within=&amp;quot;com.myApp..*&amp;quot;\/&amp;gt;\n    &amp;lt;\/weaver&amp;gt;\n\n    &amp;lt;aspects&amp;gt;\n\t\t&amp;lt;concrete-aspect name=&amp;quot;com.myApp.aspect.AspectPrecedence&amp;quot;\nprecedence=&amp;quot;com.myApp.aspect.metric.MetricsAspect,org.springframework.transaction.aspectj.AnnotationTransactionAspect&amp;quot; \/&amp;gt;\n\t\t\t\t\n\t\t&amp;lt;aspect name=&amp;quot;com.myApp.aspect.metric.MetricsAspect&amp;quot;\/&amp;gt;\n    &amp;lt;\/aspects&amp;gt;\n\n  &amp;lt;\/aspectj&amp;gt;\n<\/pre>\n<p>In the above example, the custom <strong>MetricsAspect<\/strong> aspect has been declared with higher precedence than Spring&#8217; AnnotationTransactionAspect (@Transactional).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article we&#8217;ll see how to integrate your own aspects with Spring. First we focus on load-time weaving using Spring&#8217;s dedicated AspectJ agents. Then we&#8217;ll see how to let Spring inject beans into your aspects<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,15],"tags":[33,48],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/541"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=541"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/541\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}