Recipe 14.1. Defining Singleton AspectsProblemYou want to declare that an aspect is to be instantiated as a singleton. SolutionUse the issingleton() explicit aspect instantiation policy declaration or rely on the default implicit aspect instantiation policy. DiscussionAspectJ assigns a singleton behavior to aspects by default. Every aspect you have seen so far has been a singleton because the instantiation policy has not been explicitly declared. The singleton aspect instantiation policy can be made explicit by adding the issingleton( ) statement to the aspect declaration, as shown in Example 14-1. Example 14-1. Declaring a singleton aspect explicitlypublic aspect Singleton issingleton( ) { /* Specifies calling advice whenever a method matching the following rules gets called: Class Name: MyClass Method Name: foo Method Return Type: void Method Parameters: an int followed by a String */ pointcut callPointCut( ) : call(void MyClass.foo(int, String)); // Advice declaration before( ) : callPointCut( ) && !within(Singleton +) { System.out.println( "------------------- Aspect Advice Logic --------------------"); System.out.println( "In the advice attached to the call point cut"); System.out.println( "Target: " + thisJoinPoint.getTarget( )); System.out.println( "This: " + thisJoinPoint.getThis( )); System.out.println("Aspect Instance: " + Singleton.aspectOf( )); System.out.println( "------------------------------------------------------------"); } } At the core of the singleton pattern is the goal of declaring a class that constrains itself to one object instance for the lifetime of an application. Figure 14-1 shows how each different object is advised by the same aspect instance in an application. Figure 14-1. Calls from all objects are received by the same singleton aspectSingletons are a great way for applying a common component throughout an application. Declaring your aspects as singletons allows you to share the instantiated aspect across all the areas that the aspect is applied in your application. The memory space taken by that aspect instantiation is shared across all objects and threads and can provide a useful means of sharing data when used carefully. The primary disadvantage of using traditional object-oriented singletons is that every class that uses the singleton is closely coupled to the singleton's public interface. If the singleton's public interface changes, then all of the classes that use the singleton must change. This produces a complicated ripple effect of changes throughout your application. The aspect-oriented singleton aspect does not suffer from this disadvantage. By modularizing the rules for how the singleton is applied with the behavior that the singleton provides in one place, then only the aspect needs to be amended if its behavior changes. See AlsoThe singleton pattern is discussed in more detail in Recipe 17.1; the call(Signature) pointcut is covered in Recipe Recipe 4.1; the within(TypePattern) pointcut is described in Recipe 9.1; the NOT(!) operator is described in Recipe 12.4; inheritance between aspects is described in more detail in Chapter 15. |