You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pertypewithin.xml 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <chapter id="pertypewithin" xreflabel="pertypewithin">
  2. <title>The pertypewithin Aspect Instantiation Model</title>
  3. <para>
  4. AspectJ 5 defines a new per-clause type for aspect instantiation:
  5. <literal>pertypewithin</literal>. Unlike the other per-clauses,
  6. <literal>pertypewithin</literal> takes a type pattern:
  7. </para>
  8. <programlisting><![CDATA[
  9. PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')'
  10. ]]></programlisting>
  11. <para>
  12. When an aspect is declared using the <literal>pertypewithin</literal>
  13. instantiation model, one new aspect instance will be created for each
  14. type matched by the associated type pattern.
  15. </para>
  16. <para>
  17. Pertypewithin aspects have <literal>aspectOf</literal> and
  18. <literal>hasAspect</literal> methods with the following signatures:
  19. </para>
  20. <programlisting><![CDATA[
  21. /**
  22. * return true if this aspect has an instance associated with
  23. * the given type.
  24. */
  25. public static boolean hasAspect(Class clazz)
  26. /**
  27. * return the instance associated with the given type.
  28. * Throws NoAspectBoundException if there is no such
  29. * aspect.
  30. */
  31. public static P aspectOf(Class clazz)
  32. ]]></programlisting>
  33. <para>
  34. Where <literal>P</literal> is the type of the <literal>pertypewithin</literal>
  35. aspect.
  36. </para>
  37. <para>
  38. In common with the other per-clause instantiation models, the execution
  39. of any advice declared within a <literal>pertypewithin</literal> aspect
  40. is conditional upon an implicit pointcut condition. In this case, that
  41. any join point be <literal>within</literal> the type that the executing
  42. aspect is an <literal>aspectOf</literal>. For example, given the aspect
  43. definition
  44. </para>
  45. <programlisting><![CDATA[
  46. public aspect InstanceTracking pertypewithin(org.xyz..*) {
  47. private Set<WeakReference<Object>> instances = new HashSet<WeakReference<Object>>();
  48. after(Object o) returning : execution(new(..)) {
  49. instances.add(new WeakReference<Object>(o);
  50. }
  51. public Set<Object> getInstances() {
  52. Set<Object> result = new HashSet<Object>();
  53. for(WeakReference<Object> ref : instances) {
  54. if (ref.get() != null) {
  55. result.add(ref.get());
  56. }
  57. }
  58. return result;
  59. }
  60. }
  61. ]]></programlisting>
  62. <para>
  63. Then one aspect instance will be created for each type within
  64. <literal>org.xyz..*</literal>. For each aspect instance, the
  65. after returning advice will match only the execution of constructors
  66. in the type that the aspect is an instance of. The net result is that
  67. the aspect tracks all known instances of each type within
  68. <literal>org.xyz..*</literal>. To get access to the instances, a
  69. programmer can simply write
  70. <literal>InstanceTracking.instanceOf(org.xyz.SomeType).getInstances()</literal>.
  71. </para>
  72. <para>
  73. A <literal>pertypewithin</literal> aspect may optionally be declared
  74. with a single generic type parameter. In this case, for each type
  75. <literal>T</literal> matched by the type pattern, the aspect instance
  76. created will be of type <literal>PerTypeWithinAspect&lt;T&gt;</literal>.
  77. So the previous example could also be written as:
  78. </para>
  79. <programlisting><![CDATA[
  80. public aspect InstanceTracking<T> pertypewithin(org.xyz..*) {
  81. private Set<WeakReference<T>> instances = new HashSet<WeakReference<T>>();
  82. after(T t) returning : execution(new(..)) {
  83. instances.add(new WeakReference<T>(t);
  84. }
  85. public Set<T> getInstances() {
  86. Set<T> result = new HashSet<T>();
  87. for(WeakReference<T> ref : instances) {
  88. if (ref.get() != null) {
  89. result.add(ref.get());
  90. }
  91. }
  92. return result;
  93. }
  94. }
  95. ]]></programlisting>
  96. <para>
  97. The <literal>pertypewithin</literal> aspect instantiation model should
  98. be used when the implementation of a crosscutting concern requires that
  99. some state be maintained for each type in a set of types. To maintain
  100. state for a single type, it is easier to use a static inter-type declared
  101. field. Examples of usage include instance tracking, profiling, and the
  102. implementation of a common tracing idiom that uses one Logger per
  103. traced class.
  104. </para>
  105. </chapter>