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 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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 addition, <literal>pertypewithin</literal> aspects have a
  39. <literal>getWithinTypeName</literal> method that can be called
  40. to return the package qualified name of the type for which the
  41. aspect instance has been created.
  42. </para>
  43. <programlisting><![CDATA[
  44. /**
  45. * return the package qualified name (eg. com.foo.MyClass) of the type
  46. * for which the aspect instance has been instantiated.
  47. */
  48. public String getWithinTypeName()
  49. ]]></programlisting>
  50. <para>
  51. In common with the other per-clause instantiation models, the execution
  52. of any advice declared within a <literal>pertypewithin</literal> aspect
  53. is conditional upon an implicit pointcut condition. In this case, that
  54. any join point be <literal>within</literal> the type that the executing
  55. aspect is an <literal>aspectOf</literal>. For example, given the aspect
  56. definition
  57. </para>
  58. <programlisting><![CDATA[
  59. import java.util.*;
  60. public aspect InstanceTracking pertypewithin(org.xyz..*) {
  61. // use WeakHashMap for auto-garbage collection of keys
  62. private Map<Object,Boolean> instances = new WeakHashMap<Object,Boolean>();
  63. after(Object o) returning() : execution(new(..)) && this(o) {
  64. instances.put(o,true);
  65. }
  66. public Set<?> getInstances() {
  67. return instances.keySet();
  68. }
  69. }
  70. ]]></programlisting>
  71. <para>
  72. Then one aspect instance will be created for each type within
  73. <literal>org.xyz..*</literal>. For each aspect instance, the
  74. after returning advice will match only the execution of constructors
  75. within the matched per-type-within type. The net result is that
  76. the aspect tracks all known instances of each type within
  77. <literal>org.xyz..*</literal>. To get access to the instances, a
  78. programmer can simply write
  79. <literal>InstanceTracking.aspectOf(org.xyz.SomeType.class).getInstances()</literal>.
  80. </para>
  81. <para>
  82. The <literal>pertypewithin</literal> aspect instantiation model should
  83. be used when the implementation of a crosscutting concern requires that
  84. some state be maintained for each type in a set of types. To maintain
  85. state for a single type, it is easier to use a static inter-type declared
  86. field. Examples of usage include instance tracking, profiling, and the
  87. implementation of a common tracing idiom that uses one Logger per
  88. traced class.
  89. </para>
  90. </chapter>