{"id":390,"date":"2011-12-05T01:08:07","date_gmt":"2011-12-05T00:08:07","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=390"},"modified":"2011-12-05T01:08:07","modified_gmt":"2011-12-05T00:08:07","slug":"advanced-aspectj-part-i-instanciation-model","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=390","title":{"rendered":"Advanced AspectJ Part I : Instanciation model"},"content":{"rendered":"<p>In this serie of articles we&#8217;ll talk about advanced features in AspectJ. This will exclude for sure popular AspectJ construct like method execution or within join points.<\/p>\n<p>This first article deals with the instanciation model of AspectJ<\/p>\n<p>As support for our talk, we&#8217;ll create a <strong>logger injection<\/strong> using annotation and AspectJ.<\/p>\n<p><!--more--><\/p>\n<blockquote><p>This entire serie of articles on AspectJ focuses on the code using <strong>code-style<\/strong> aspect rather than @AspectJ annotation. We want to keep as close as possible to the original AspectJ semantics<\/p><\/blockquote>\n<h1>I Instanciation model<\/h1>\n<h3>A Singleton<\/h3>\n<p>&nbsp;<br \/>\nSimilar to a Java class, any aspect in AspectJ needs to be instanciated at runtime to work. But unlike Java classes, aspects are not created using the <strong>new <\/strong>keyword. They are created instead at the runtime by the JVM based on their instanciation model declared in the <em>.aj<\/em> source file.<\/p>\n<p>By default, a declared an aspect is a singleton e.g. there is only one instance of this aspect per classloader (and not per JVM). This instance will be destroyed only when the class loader is garbaged.<\/p>\n<pre class=\"brush: java; highlight: [1]; title: ; wrap-lines: false; notranslate\" title=\"\">\n   public aspect MyAspect {\n      ...\n   }\n<\/pre>\n<p>or<\/p>\n<pre class=\"brush: java; highlight: [1]; title: ; wrap-lines: false; notranslate\" title=\"\">\n   public aspect MyAspect issingleton() {\n      ...\n   }\n<\/pre>\n<p>If your aspect contains private attributes holding data relative to class instances, your aspect is statefull at it&#8217;s high time to look at other alternative instanciation models<br \/>\n&nbsp;<\/p>\n<h3>B Per object instance<\/h3>\n<p>It is possible to create one instance of the aspect per object being advised. For this the syntax is:<\/p>\n<ul>\n<li><em>public|abstract|final<\/em> aspect xxxx <strong>perthis(Pointcut)<\/strong><\/li>\n<li><em>public|abstract|final<\/em> aspect xxxx <strong>pertarget(Pointcut)<\/strong><\/li>\n<\/ul>\n<p>where <strong>PointCut<\/strong> references a declared pointcut in this aspect.<\/p>\n<p>Example is better than words, let&#8217;s see how it works:<\/p>\n<pre class=\"brush: java; highlight: [3,5]; title: ; wrap-lines: false; notranslate\" title=\"\">\n   import org.springframework.transaction.annotation.Transactional;\n\n   public aspect PerObjectAspect perthis(transactionalMethod()) {\n      \n      pointcut transactionalMethod() : execution(@Transactional * *(..));\n      ...\n      ...\n   }\n<\/pre>\n<p>The above aspect will create as many instances as there are objects executing join point selected by <em>transactionalMethod()<\/em> pointcut e.g. objects executing a <em>@Transactional<\/em> method.<\/p>\n<p>The semantic difference between perthis() and pertarget() is simple:<\/p>\n<ul>\n<li><em>perthis()<\/em> creates an instance for every <strong>executing object<\/strong> (&#8220;this&#8221;) at the pointcuts selected by the join point<\/li>\n<li><em>pertarget()<\/em> creates an instance for every <strong>target object<\/strong> (&#8220;this&#8221;) at the pointcuts selected by the join point<\/li>\n<\/ul>\n<p>In the above example, for the pointcut <em>execution(@Transactional * *(..))<\/em>, the <strong>executing<\/strong> object is the same as the <strong>target<\/strong> object. This is the class instance executing the <em>@Transactional<\/em> method.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perthis.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perthis.png\" alt=\"\" title=\"Perthis\" width=\"484\" height=\"280\" class=\"aligncenter size-full wp-image-396\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perthis.png 484w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perthis-300x174.png 300w\" sizes=\"(max-width: 484px) 100vw, 484px\" \/><\/a><\/p>\n<p>If we change the point cut to <em>call(@Transactional * *(..))<\/em>, the <strong>executing<\/strong> object is the caller and the <strong>target<\/strong> object is the one executing the <em>@Transactional<\/em> method.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/pertarget.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/pertarget.png\" alt=\"\" title=\"Pertarget\" width=\"484\" height=\"280\" class=\"aligncenter size-full wp-image-397\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/pertarget.png 484w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/pertarget-300x174.png 300w\" sizes=\"(max-width: 484px) 100vw, 484px\" \/><\/a><\/p>\n<p>The lifecycle of the aspect instance is directly linked to the lifecycle of the advise object. If this object is garbaged by the GC, the aspect instance will be destroyed as well.<\/p>\n<p>&nbsp;<\/p>\n<h3>C Per control flow instance<\/h3>\n<p>Sometime it is necessary to create an aspect instance only for some particular control flow ((method calls stack). For this the syntax is:<\/p>\n<ul>\n<li><em>public|abstract|final<\/em> aspect xxxx <strong>percflow(Pointcut)<\/strong><\/li>\n<li><em>public|abstract|final<\/em> aspect xxxx <strong>percflowbelow(Pointcut)<\/strong><\/li>\n<\/ul>\n<p><em>percflow(Pointcut)<\/em> will create an aspect instance for each control flow selected by the Pointcut.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflow.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflow.png\" alt=\"\" title=\"Perflow\" width=\"560\" height=\"408\" class=\"aligncenter size-full wp-image-399\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflow.png 560w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflow-300x219.png 300w\" sizes=\"(max-width: 560px) 100vw, 560px\" \/><\/a><\/p>\n<p><em>percflowbelow(Pointcut)<\/em> is similar to perflow(Pointcut), excluding the original method call.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflowbelow.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflowbelow.png\" alt=\"\" title=\"Perflowbelow\" width=\"540\" height=\"408\" class=\"aligncenter size-full wp-image-400\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflowbelow.png 540w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/perflowbelow-300x227.png 300w\" sizes=\"(max-width: 540px) 100vw, 540px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h3>D Per type instance<\/h3>\n<p>The last instanciation model is <strong>per type (class, interface or even aspect)<\/strong>. It is very similar to the per object instanciation except that now one aspect instance is created per type. <\/p>\n<pre class=\"brush: java; highlight: [1]; title: ; wrap-lines: false; notranslate\" title=\"\">\n   public aspect PerTypeAspect pertypewithin(com.project.*) {\n      ...\n   }\n<\/pre>\n<p>The above declaration will create one aspect instance per type (class, interface or aspect itself) in the <em>com.project<\/em> package and all its sub-packages.<\/p>\n<h1>II Accessing the instance<\/h1>\n<p>Since more than one instance of the aspect can exist at a time, we need a way to access them. The AspectJ language provide a usefull static method <em>aspectOf()<\/em> on each aspect to access the created instance.<\/p>\n<p>For example, to access the singleton instance of the <strong>MySingletonAspect<\/strong>, we just need to call <strong>MySingletonAspect<\/strong>.<em>aspectOf()<\/em><\/p>\n<p>Below is a table summerizing the usage of this method:<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/accessingaspectinstance.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/accessingaspectinstance.png\" alt=\"\" title=\"AccessingAspectInstance\" width=\"528\" height=\"103\" class=\"aligncenter size-full wp-image-403\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/accessingaspectinstance.png 528w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2011\/12\/accessingaspectinstance-300x59.png 300w\" sizes=\"(max-width: 528px) 100vw, 528px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>III Injecting a logger<\/h1>\n<p>We would like to inject automatically a logger into each class declaring an attribute annotated with <em>@InjectedLogger<\/em>. It will save us from typing<\/p>\n<p><code>private static final Logger logger = Logger.getLogger(MyClass.class);<\/code><\/p>\n<p>For this, we define the <em>@InjectedLogger<\/em> annotation.<\/p>\n<h5><strong>1) InjectedLogger<\/strong><\/h5>\n<pre class=\"brush: java; highlight: [11]; title: ; wrap-lines: false; notranslate\" title=\"\">\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.FIELD)\n@Documented\npublic @interface InjectedLogger\n{\n\t\/**\n\t * Name of the logger. By default empty When empty, \n\t * the logger name will be replaced by the canonical class \n\t * name of the field annotated with @InjectedLogger\n\t *\/\n\tString loggerName() default &amp;quot;&amp;quot;;\n}\n<\/pre>\n<p>When used with no attribute, the injected logger name is set by default to the canonical class name of the field annotated with <em>@InjectedLogger<\/em>. If a <em>loggerName<\/em> attribute is provided, the injected logger will use this name.<\/p>\n<p>A test class to exemplify the usage of this annotation:<\/p>\n<h5><strong>2) TestInjectedLogger<\/strong><\/h5>\n<pre class=\"brush: java; highlight: [4,5]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic class TestInjectedLogger\n{\n\n\t@InjectedLogger\n\tprivate static Logger staticLogger;\n\n\tpublic void staticLogger()\n\t{\n\t\tTestInjectedLogger.staticLogger.info(&amp;quot;Static logger called : &amp;quot; + TestInjectedLogger.staticLogger);\n\t}\n\n\tpublic static void main(String[] args)\n\t{\n\n\t\tTestInjectedLogger testInjectedLogger = new TestInjectedLogger();\n\t\ttestInjectedLogger.staticLogger();\n\n\t}\n}\n<\/pre>\n<p>Finally the aspect implementing the feature:<\/p>\n<h5><strong>3) LoggerInjectionAspect<\/strong><\/h5>\n<pre class=\"brush: java; highlight: [1,3,5,33]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic aspect LoggerInjectionAspect perthis(accessLogger())\n{\n\tprivate Logger logger = null;\n\t\n\tpointcut accessLogger(): getLogger(InjectedLogger) || setLogger(InjectedLogger,Logger);\n\t\n\tpointcut getLogger(InjectedLogger annot)\n\t: get(@InjectedLogger * *) &amp;amp;&amp;amp; @annotation(annot);\n\t\n\tpointcut setLogger(InjectedLogger annot,Logger logger)\n\t: set(@InjectedLogger * *) &amp;amp;&amp;amp; args(logger) &amp;amp;&amp;amp; @annotation(annot);\n\t\n\t\/\/ Around getLogger() advice\n\tLogger around(InjectedLogger annot): getLogger(annot)\n\t{\n\t\tif(this.logger == null)\n\t\t{\n\t\t\tretrieveLogger(annot,thisJoinPointStaticPart);\n\t\t}\n\t\treturn this.logger;\n\t}\n\n\t\/\/ Around setLogger() advice\t\n\tObject around(InjectedLogger annot,Logger arg): setLogger(annot,arg)\n\t{\n\t\tif(this.logger == null)\n\t\t{\n\t\t\tretrieveLogger(annot,thisJoinPointStaticPart);\n\t\t}\n\t\treturn proceed(annot,this.logger);\n\t}\n\t\n\tprivate void retrieveLogger(InjectedLogger annot,StaticPart jpStatic)\n\t{\n\t\tif(StringUtils.isNotBlank(annot.loggerName()))\n\t\t{\n\t\t\tthis.logger = Logger.getLogger(annot.loggerName());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.logger = Logger.getLogger(jpStatic.getSignature().getDeclaringTypeName());\t\n\t\t}\n\t}\n}\n<\/pre>\n<p>First the aspect declares a private attribute <strong>logger<\/strong> (<strong>line 32<\/strong>). Similar to a class, an aspect can have attributes and methods.<\/p>\n<p>Then we declare an <strong>abstract poincut<\/strong> <em>accessLogger()<\/em> whose definition relies on the concrete poincuts <em>getLogger()<\/em> &amp; <em>setLogger()<\/em> (<strong>line 5<\/strong>)<\/p>\n<p>The pointcut <em>getLogger()<\/em> is triggered when any attribute annotated with <em>@InjectedLogger<\/em> is <strong>accessed<\/strong> (field reference)<\/p>\n<p>The pointcut <em>setLogger()<\/em> is triggered when any attribute annotated with <em>@InjectedLogger<\/em> is <strong>set<\/strong><\/p>\n<p>We also define a private method <em>retrieveLogger()<\/em> to effectively retrieve the Logger instance from Log4J Logger factory using the canonical class name or provided <em>loggerName<\/em> (<strong>line 32<\/strong>).<\/p>\n<p>The advice on <em>getLogger()<\/em> will return the private logger instance if it is not null or call first the <em>retrieveLogger()<\/em> method to initialize it.<\/p>\n<p>The advice on <em>setLogger()<\/em> also initializes the logger attribute when necessary. It then assigns it to the target attribute annotated with <em>@InjectedLogger<\/em>. Exemple below:<\/p>\n<pre class=\"brush: java; highlight: [8]; title: ; wrap-lines: false; notranslate\" title=\"\">\npublic class TestInjectedLogger\n{\n\t@InjectedLogger\n\tprivate static Logger staticLogger;\n\n\t...\n\t...\n\tTestInjectedLogger.staticLogger = Logger.getLogger(&amp;quot;testLogger&amp;quot;);\n\t...\n\t...\n<\/pre>\n<p>In the code above, the advice on <em>setLogger()<\/em> will intercept the assignment at <strong>line 8<\/strong> to substitute its own instance of <em>logger<\/em>. Consequently, the staticLogger attribute is pointing to the logger &#8220;com&#8230;TestInjectedLogger&#8221; instead of &#8220;testLogger&#8221;.<\/p>\n<p>Since the aspect has a private attribute storing the real logger for the target class (statefull aspect), the instanciation model should meet this requirement. At <strong>line 1<\/strong> we define the instanciation model as <em>perthis(accessLogger())<\/em> so there will be one instance of LoggerInjectionAspect for each object having an @InjectedLogger annotated attribute.<\/p>\n<p>While running the class TestInjectedLogger, we got the following output:<\/p>\n<p><code>INFO  [01:05:34,033] com.test.TestInjectedLogger@staticLogger: Static logger called : org.apache.log4j.Logger@<strong>1b3f829<\/strong><\/code> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this serie of articles we&#8217;ll talk about advanced features in AspectJ. This will exclude for sure popular AspectJ construct like method execution or within join points. This first article deals with the instanciation model of AspectJ As support for&#8230;<br \/><a class=\"read-more-button\" href=\"https:\/\/www.doanduyhai.com\/blog\/?p=390\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,4],"tags":[33,37],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/390"}],"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=390"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/390\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}