Aspect-Oriented Programming

judgedrunkshipΔιακομιστές

17 Νοε 2013 (πριν από 3 χρόνια και 8 μήνες)

111 εμφανίσεις

Aspect
-
Oriented Programming

(AOP)

Dr. Rebhi S. Baraka (
rbaraka@iugaza.edu
)

Faculty of Information Technology

Islamic University of Gaza

IT faculty seminar, October
28
,
2008


Outline


What is a Concern?



Crosscutting concerns


Crosscutting Example


The Solution with Aspects


Aspect
-
Oriented Programming (AOP)
-

AspectJ


join points


pointcuts


Advices


Intertype declarations


Aspects


Demo


What is a Concern?


A programming methodology is called
Aspect
-
Oriented
if it provides a
clean solution to separate concerns that
would otherwise be cross
-
cutting.


Generally speaking, A concern is anything that is of
interest to some stakeholder, whether an end user, a
project sponsor, or even a developer.


Concerns such as: XML parsing , UML pattern
matching, Logging and Session management are
concerns of a software system.


Separation of Concerns
is an important principle of
Software design.



Crosscutting concerns



Separation of concerns is achieved through
modularity


The smallest unit suitable for a module is a
class in OOP



This is insufficient


we still get crosscutting


Across
-
cutting concern is one that needs to be
addressed in more than one of the modules in
the hierarchical structure of the software.



Crosscutting concerns


formal definition:


“whenever two properties being programmed
must compose differently and yet be coordinated”


crosscutting leads to


Inability to keep peers separate


code scattering


code tangling


Inability to keep extensions separate


Cross
-
cutting concerns are also called
aspects.


See later slides

Crosscutting example


code in
org.apache.tomcat



The logging module is represented by the red lines


It is handled by code that is scattered over almost all classes




Crosscutting concerns


Cross
-
cutting concerns pose problems for
standard, e.g. OO programming techniques:


hard and error
-
prone to introduce in an existing
system


hard to change afterwards


hard to understand/explain to newcomers


Cross
-
cutting implementation of cross
-
cutting
concerns does
not provide separation of
concerns.


Crosscutting Example

Hotel Management System made
up of interconnected components


The Reserve Room, Check In, and Check Out
components encapsulate the business and
control logic for the respective functionalities.



The reservation and the room components
maintain information in a data store.


This separation of roles and responsibilities
across components is essential to a system
that is resilient (one that will not easily break
when changes are introduced).

A hotel Management System made up of the following
interconnected components:


The Customer Screen and Staff Screen components deal with presenting
information to the users and accepting and validating input from them.

Crosscutting Example


Problems:
Inability to Keep Peers Separate

Tangling and scattering when
realizing peers


Peers are crosscutting concerns
that are distinct from each other.


Reserve Room, Check In
Customer, and Check Out
Customer are peers


These concerns do not need each
other to exist.


However, when you start to
implement peers in the same
system, you find significant
overlap between them


Components are limited in keeping peers
separate


It results in
tangling

and
scattering

Crosscutting Example


Problems:
Inability to Keep Peers Separate

Tangling and scattering when
realizing peers

Tangling


A component contains the
implementation (i.e., code) to
satisfy different concerns. For
example, the Room component is
involved in the realization of three
different concerns.


This means that we need to
understand a diverse set of
concerns.


The component, instead of single
-
mindedly fulfilling a particular
concern, participates in many.


This hinders understandability and
makes the learning curve steeper
for developers.

Crosscutting Example


Problems:
Inability to Keep Peers Separate

Tangling and scattering when
realizing peers

Scattering


codes that realize a particular
concern are spread across multiple
components.


For example, the realization of
CheckIn

Customer imposes additional
behaviors on four components.


So, if ever the requirements about
that concern change, or if the design
of that concern changes, you must
update many components.




scattering means that it is not easy to understand
the internals of a system.



For instance, it is not easy to uncover
requirements by reading the source code of each
component or a set of components

Crosscutting Example


Problems:
Inability to Keep Extensions Separate



The second kind of crosscutting concern is what we call
extensions.



Extensions are components that you define on top of a
base. They represent additional service or features.

o
For example, the Hotel Management System has a waiting list for
room reservations. If there are no rooms, the system puts the
customer on a waiting list.

o
Thus, the provision of a waiting list is an extension of Reserve
Room.



Keeping extensions separate is a technique to make a
complex problem understandable. You do not want to be
entangled by too many issues, so you keep them separate
as extensions.

Crosscutting Example

Extensions inserted intrusively



To incorporate the Waiting List extension, a corresponding component is
added (shown in a darker shade).

o

But in addition, you need to add some code fragments in the
Reserve Room component at a particular location, which we call an
extension point. The purpose of this code fragment is to connect or
invoke the Waiting List component.


Problems:
Inability to Keep Extensions Separate



This code fragment is affectionately known
as glue code. In aspect
-
speak, such a
change is known as
intrusive
.

The Solution with Aspects


Components (e.g., classes) cannot keep crosscutting
concerns separate all the way down to code.


To keep crosscutting concerns separate throughout
the life cycle of the module from requirements to
analysis, design, code, and test, we need two
techniques:



a concern separation technique (using aspects)


and a concern composition technique.


An
Aspect

is a programming construct in AOP that gives
the ability to add class extensions into existing classes. An
aspect in AOP contains pointcuts, advices, and intertype
declarations.


The Solution with Aspects


Keeping Peers Separate with Aspects


Functionalities (represented horizontally) cut
across classes in the system (shown as boxes).


Each box lists the operations imposed on the respective
classes.

Classes composed from different concerns

The Solution
Keeping Peers Separate with Aspects

For example, line
3
adds the operation
assignCustomer()
into the Room class. Notice
that although this operation is part of the Room class, it is defined outside the Room
class itself. Thus, aspect orientation escapes from the restriction on a class property
needing to be defined within the traditional class modularity. This allows us alternate
ways of organizing code
---
one that keeps the realization of peer concerns separate.

1
. public aspect CheckInCustomer {

2
. ...

3
. public void Room.assignCustomer ()

4
. {

5
. // code to check in customer

6
. }

7
. public void Reservation.consume()

8
. {

9
. // code to consume reservation

10
. }

11
. public void Payment.createBill()

12
. {

13
. // code to generate an initial outstanding bill

14
. }

15
. ...

16
. }


Keeping Extensions Separate with Aspects


Extensions are add
-
ons to some base behavior. In this case, we have a base
reserve room functionality, which we want to extend.


Suppose that you want additional functionalities (i.e., extensions) specifically
to ensure that only authorized users are permitted to make a room
reservation, and if there are no Rooms available, you want to put the user on
a waiting list. This can be achieved in two steps:

makeReservation operation


Identify the extension points
in the existing operation in
which the behavior needs to
be extended.


Define the additional
behavior that will be used to
extend the behavior at these
extension points.

The Solution
Keeping Extensions Separate with Aspects


the additional behavior to check for authorization has been
composed into the existing operation at marker . At marker ,
instead of displaying a message indicating there are no rooms,
the customer is put in a queue.


the original makeReservation operation is now entangled with
code needed to fulfill requirements not directly related to
making reservations.


Worse, it makes the

makeReservation operation less

understandable for the developer.

makeReservation modified with
authorization and waiting list

The Solution
Keeping Extensions Separate with Aspects

1
. class ReserveRoomHandler {

2
. ...

3
. public void makeReservation() throws NoRoomException

4
. {

5
. if(theRoom.getQuantityAvailable()<=
0
) {

6
. throw new NoRoomException () ;

7
. }

8
. createReservation() ;

9
. }

10
. ...

11
. }


Simplified Source Code for ReserveRoomHandler

The
makeReservation
)(

operation makes two calls
:


getQuantityAvailable
)(

operation belongs to the

Room

class, and it returns
the number of rooms available.


CreateReservation
)(

operation creates a reservation record in the data store
if rooms are indeed available
.

The Solution
Keeping Extensions Separate with Aspects

Handle Waiting List:
aspects extend existing operations
through
pointcuts

and advices.


A
pointcut

identifies an execution point in the base.


Lines
3
and
4
show a
pointcut

named
makingReservation

that refers to the execution
of the
makeReservation

operation.


An
advice

describes the additional behaviors that will run when
execution reaches that point.


Lines
6
,
7
, and
8
show an advice that occurs when the operation referenced by this
pointcut

throws a
NoRoomException

(i.e., when
makeReservation
() throws a
NoRoomException
).


1
. aspect HandleWaitingList {

2
. ...

3
. pointcut makingReservation() :

4
. execution(void ReserveRoomHandler.makeReservation()) ;

5
. ...

6
. after throwing (NoRoomException e) : makingReservation() {

7
. // code to add customer to waiting list ;

8
. }

9
. }

Simplified Source Code to Handle Waiting List

The Solution
Keeping Extensions Separate with Aspects


Thus, AOP allows you to extend existing operations with
additional behaviors. In this way,


the original operation (i.e., makeReservation()) is not
entangled with the extension.


Thus, the extension is kept separate from the developer's
perspective.

The Solution
Keeping Extensions Separate with Aspects


Check Authorization:
Instead of specifying one pointcut for
each transaction, AOP lets us use a limited form of pattern
matching to specify multiple execution points at once


These execution points are collectively called performingTransaction, and we
name the pointcut accordingly in lines
2
,
3
, and
4


In lines
2
,
3
, and
4
, the performingTransaction pointcut identifies all
operations in the ReserveRoomHandler and CheckInHandler classes using the
wildcard character *.

The Solution
Keeping Extensions Separate with Aspects

1
. aspect HandleAuthorization {

2
. pointcut performingTransaction ():

3
. call(void ReserveRoomHandler.*(..))

4
. || call(void CheckInHandler.*(..));

5
. void around () : performingTransaction() {

6
. if(isAuthorized()) {

7
. proceed() ;

8
. }

9
. }

10
. }

Simplified Source Code to Handle Authorization


Check Authorization


By default, the
around

advice causes the execution of the existing operations
in the
ReserveRoomHandler

or
CheckInHandler

to be bypassed (i.e., to go
"around" them).


The if condition in line
6
checks if there is sufficient authorization. If so, the
advice invokes the existing operation using a proceed keyword (line
7
); that
is, you proceed with the existing operation.

The Solution
Keeping Extensions Separate with Aspects

1
. aspect HandleAuthorization {

2
. pointcut performingTransaction ():

3
. call(void ReserveRoomHandler.*(..))

4
. || call(void CheckInHandler.*(..));

5
. void around () : performingTransaction() {

6
. if(isAuthorized()) {

7
. proceed() ;

8
. }

9
. }

10
. }

Simplified Source Code to Handle Authorization

Aspect
-
Oriented Programming


There are various Aspect
-
Oriented methods.


They differ in the kinds of aspects they can
address and


In the ways aspects are expressed.


History


research started in early
90
’s at Xerox PARC


research team led by Greg Kiczales


started with metaobject and reflection protocols,
led to AOP


other teams worked on AOP concepts in parallel,
but AOP itself was formalized by Kiczales et al.



AspectJ


Popular AOP tool that adds constructs for
aspects to Java


Developed in
1997
.


First public release in
1998
.


Version
1.0
released in
2001


Latest version is
1.6


Contains a compiler (ajc) that is used for


Compile
-
time weaving of source code



AspectJ


AspectJ is an extension to the Java language with
new constructs to separate and modularize
concerns:


Intertype declarations
allow you to compose new
features (attributes, operations, and relationships)
into existing classes.


join points
identifies interesting points in the code


pointcuts

groups join points together


Advices

provide the means to extend existing
operations at extension points designated by
pointcuts

in AOP.


Aspects

are a kind of building block used to organize
intertype declarations and advices. Aspects can
generalize other aspects.

Join Points


Join points are events in the control flow of a
program


Examples of events that occur during the execution
of a program are a call being made to a method, a
field being updated, an expression being evaluated,
the fourth line of code in the Foo.bar() method
being executed, and so on.


A join point model determines which events
will be exposed as join points (and hence can
be referred to in pointcut expressions), and
which will not

Join Points


AspectJ exposes join points for the following:


A call to a method or constructor


The execution of a method, constructor, or advice
body


The access or update of a field


The initialization of classes and objects


The execution of an exception handler


Join points are dynamic: they arise during
program execution.


So the best way to illustrate them is through an
object collaboration or sequence diagram.

Join points in program execution sequence

diagram

See the notes
below for the
explanation of the
diagram

Pointcuts


A pointcut is (a predicate) used to select join points.


It acts as a filter, matching join points that meet its
specification, and blocking all others.



For example, the pointcut call(String
toString
()) will match
any call made to a method named
toString

that takes no
arguments and returns a String.


AspectJ supports three types of
pointcuts
:

1.
matches join points based on the kind of join point

2.
matches join points based on scope

3.
matches join points based on context information at the join
point itself

Pointcuts

1
. Pointcuts that match join points based on the kind of join point


For example, is it a method call, the execution of an exception handler, the
static initialization of a class, and so on).

Pointcut Expression

Meaning

execution(public * get*(..))

The execution of any public
method returning any type
and taking any arguments,
where the method name
begins with "get."

set(
int

Point.x
)

䅮⁵A摡t攠t漠t桥⁶慬略映t桥h
fi敬搠x i渠t桥hP潩ot⁣污獳

桡湤n敲(
I佅O捥pti潮


周攠
ex捥捵瑩潮

潦o慮 ex捥pti潮o
桡湤n敲⁦潲
I佅O捥pti潮

潲 慮礠
潦oit猠獵扣s慳獥献

c慬l⠪ 朮xXz..⨨..⤩

䄠A慬l t漠慮礠Xet桯搠摥捬慲敤e
i渠愠a祰攠i渠愠a慣a慧a 睨潳攠
湡浥⁢敧 湳⁷nt栠≯h朮xXz."

stati捩湩瑩慬azati潮

(
卥Si慬iz慢le


周攠etati挠i湩tializati潮o潦o慮礠
獥si慬iz慢le

捬c獳s

Example Pointcut Expressions
Matching on Kind of Join Point


The designators are:
call
,
execution
,
get
,
set
,
handler
,
adviceexecution
,
staticinitialization
,
preinitialization
, and
initialization

Pointcuts

2
. Pointcuts that match join points based on scope

For example, is the currently executing object an instance of a
given type?


scoping pointcut designators are
within
,
withincode
,
cflow
,
and
cflowbelow
.


The
within

pointcut matches any join point where the associated source
code is defined within a given scope (such as a type or package).


The
withincode

pointcut matches join points where the associated
source code is defined within a given set of methods or constructors.


The
cflow

and
cflowbelow

pointcuts match join points based on the
control flow in which they occur.


For example, the pointcut expression
cflow(execution(* IBankAccount.*(..))
matches any join point arising as a result of the execution of a method defined
by the IBankAccount interface, including all join points in the method's call
graph.

Pointcuts

3
. Pointcuts that match join points based on context
information at the join point itself


For example, does the code that gave rise to the join point
reside within a certain package? Has the join point occurred
within the control flow of a given operation?


context matching pointcut designators are
this
,
target
, and
args
.


Examples:



The expression
this(String)

matches any join point where the
currently executing object is an instance of String.


The expression
target(Foo)
matches any join point where the target
object (of a call for example) is an instance of Foo.

Pointcuts


Pointcuts can be named or anonymous.


Naming pointcuts improves the clarity of our code.


Naming pointcuts provides for abstraction, encapsulation, and reuse.


Abstraction is provided by the ability to refer to the pointcut by name (for
example, jdbcCall) rather than by the detailed expression.



Encapsulation arises because you are not aware of the detailed pointcut
expression when referring to a pointcut by name.


Reuse occurs because you can refer to a named pointcut in other pointcut
expressions.


Pointcut declarations can occur inside both classes and aspects,
but not in interfaces. The general form of a pointcut declaration
is as follows:

[visibility
-
modifier] pointcut name( ParameterList ) : PointcutExpr ;


visibility
-
modifier
: public, private, protected, or package


Pointcuts

Example pointcuts:

pointcut jdbcCall() :


call(* java.sql..*(..)) ||


call(* javax.sql..*(..));

pointcut inPersistenceLayer() : within(insurance.dao..*);

pointcut dbExceptionHandler() : handler(SQLException+);


pointcut leakedException() :


dbExceptionHandler() &&


!inPersistenceLayer();


Note:
This example also illustrates the powerful ability to compose
pointcuts to create new pointcut expressions using the &&, ||,
and ! operators.

Advices


Pointcuts are predicates that match join points, and
advice specifies what to do at those join points.


Each piece of advice is associated with a pointcut
(named or anonymous) and specifies behavior that it
wants to execute before, after, or around, the join
points that the pointcut matches.


An advice declaration may contain parameters whose
values can be referenced in the body of the advice.


Unlike method calls, in which parameter values are
explicitly passed by the caller, the parameter values
are provided by the pointcut.

Advices


Because advice is always invoked implicitly, there is no
need to name it. (You cannot call advice by name, or
by any other means.)



For the same reason, there are no visibility modifiers
for advice (e.g., public or private).


The basic forms of advice declarations for before,
after, and around advice are as follows:


before(ParameterList) : PointcutExpr{ ... };


after(ParameterList) returning : PointcutExpr { ... };



after(ParameterList) throwing : PointcutExpr { ... };


Type around(ParameterList) : PointcutExpr { ... };

Advices


Example:

using advice with an anonymous pointcut:

after(Account acc, Money amount) returning:


execution(void Account.*(Money)) &&


args(amount) &&


this(acc) {


acc.getStatement().recordTransaction( thisJoinPointStaticPart, amount);


}

The same example rewritten to use a named pointcut:

pointcut accountUpdate(Account acc, Money amount) :


execution(void Account.*(Money)) &&


args(amount) &&


this(acc);

after(Account acc, Money amount) returning :


accountUpdate(acc,amount) {


acc.getStatement().recordTransaction( thisJoinPointStaticPart, amount);


}

Showing advice invocations in sequence diagrams

Inter
-
Type Declarations


inter
-
type declarations are a statement that an aspect takes complete
responsibility for certain capabilities on behalf of other types (the
"targets" of the inter
-
type declarations).


The most basic forms of inter
-
type declarations are for methods and
fields.


An inter
-
type declaration inside an aspect looks just like the definition of a
normal method or field in the aspect, except that the method or field
name is preceded by a type name. Here's a simple example:

public aspect AccountSession{


private SessionContext Account.context;


public SessionContext Account.getSessionContext() {


return context;


}


public void Account.setSessionContext(SessionContext ctx) {


context = ctx;


}

}

Inter
-
Type Declarations

Representing the effect of inter
-
type declarations in sequence diagrams

Inter
-
Type Declarations


Inter
-
Type Field Declarations


[Modifiers] FieldType TargetType.Id;


Example:

public Long AddressImpl.id;

This declares a public field called
id
, which the
HibernateManager

aspect manages on behalf of the
AddressImpl

class.


Example:
removing the definition of the listeners field from
PolicyImpl and replacing it with an inter
-
type declared field


To:

public aspect
PolicyChangeNotification

{

...

private Set
PolicyImpl.listeners

= new
HashSet
();


...

}

From:

public class
PolicyImpl

{


...

private Set listeners = new
HashSet
();


...

}

Inter
-
Type Declarations


Inter
-
Type Method Declarations


[Modifiers] ReturnType TargetType.Id(Formals) [throws TypeList] { Body };


Example:
move the methods associated with listener registration and
notification from PolicyImpl to the PolicyChange Notification aspect.


private void
PolicyImpl.notifyListeners
() {


if (listeners == null) return;


for (
Iterator

iter

=
listeners.iterator
();

iter.hasNext
();)


{


PolicyListener

l = (
PolicyListener
)
iter.next
();


l.policyUpdated
(this);


}

}


private Set
PolicyImpl.listeners

= new
HashSet
();


public void
PolicyImpl.addPolicyListener
(


PolicyListener

l) {


this.listeners.add
(l);

}



public
boolean

PolicyImpl.removePolicyListener
(


PolicyListener

l) {


return
this.listeners.remove
(l);

}

Inter
-
Type Declarations


Inter
-
Type Constructor Declarations


[Modifiers] TargetType.new(Formals) [throws TypeList] { Body };


Example:


public aspect
HibernateManager

{

...


// meeting
hibernate's

requirements


//
---------------------------------------



public Long AddressImpl.id;



public
AddressImpl.new
() {}


public
ClaimImpl.new
() {}


public
PolicyImpl.new
() {}


public
LifePolicyImpl.new
() {}


public
HousePolicyImpl.new
() {}


public
AutoPolicyImpl.new
() {}


public
Schedule.new
() {}


public
Automobile.new
() {}


...

}

Using Pointcuts and Advice with
Inter
-
Type Declarations


The
call

and
execution

join points for inter
-
type
declared methods and constructors are the same as
if those methods and constructors had been
declared directly in the target type.


The
get

and
set

join points for inter
-
type declared
fields are the same as if those fields had been
declared directly on the target type.


when using the
within

scoping pointcut designator,
inter
-
type declared members are within the aspect,
not within the target type.

Using Pointcuts and Advice with
Inter
-
Type Declarations


Example:

public aspect
CountListeners

{


pointcut add () :


execution(*
PolicyImpl.addPolicyListener
(..));



after () returning : add () {


count++;


}


pointcut remove () :


execution(*
PolicyImpl.removePolicyListener
(..));



after () returning : remove () {


count
--
;


}


private
int

count;

}

Aspects


Aspects are the unit of modularity by which AspectJ implements
crosscutting concerns.


The general form of an aspect declaration is as follows:



[ privileged ] [ Modifiers ] aspect id [extends Type]




[implements TypeList] [PerClause] { Body }


an aspect may contain definitions of constructors, fields, methods, and
pointcuts.


It may also contain inner classes, aspects, and interfaces.



In addition to these features that are shared with classes, aspects can also
contain advice and inter
-
type declarations.


every aspect has a default constructor.

aspect
AnAspect

{


static {


// once per type initialization


}


public
AnAspect
() {


// once per instance initialization


}

}



an aspect can gain
additional access through
the
privileged

keyword



to specify alternative
aspect instantiation models
by using
per
-
clauses

in the
aspect definition.

Aspect Instantiation


At runtime AspectJ creates instances of aspects, and all
methods and advice within an aspect run in the context of an
aspect instance (available via
this

in the body of the method
or advice).


Singleton aspects are the default (you can optionally specify
issingleton()
for the
per
-
clause

of a singleton aspect but it is
not required), and result in the creation of a single aspect
instance of an aspect type within the JVM.


There are four additional aspect instantiation models
available:
perthis
,
pertarget
,
percflow
, and
percflowbelow
.
Each form takes a pointcut expression as an argument.


Aspect Instantiation


The
perthis

instantiation model creates an aspect instance for
each unique object bound to this at join points matched by
the pointcut expression.


The
pertarget

instantiation model is similar, but creates an
aspect instance for each unique object bound to target at
matched join points.


The
percflow

and
percflowbelow

instantiation models create
aspect instances that live for the duration of the control flow,
or the control flow below, join points matched by the
pointcut.

Aspect Instantiation

Singleton Aspects


This is the default behavior.


The aspect instance is created on first active use and exists for
the lifetime of the program execution.


For singleton aspects, the
aspectOf

and
hasAspect

methods
take no arguments:

public static <AnAspect> aspectOf();

public static boolean hasAspect();


The
hasAspect()
method determines whether an instance of a
particular aspect is available and always returns true for
singleton aspects.


The
aspectOf()
method returns the singleton instance. Example:

SerializationBasedPersistence sbpAspect = SerializationBasedPersistence.aspectOf();

Is used to access the SerializationBasedPersistence aspect instance

Aspect Instantiation

Per
-
This Aspects


The
perthis(pointcut_expression)
model creates new aspect
instances as follows: For each join point matched by the
pointcut expression, if this is bound to an object instance, and
an aspect has not already been created for that instance, a
new aspect is created and associated with it.

public aspect
MultipleReadersSingleWriter

perthis
(
readMethod
() ||
writeMethod
() ) {



private
ReadWriteLock

rw

=


new
WriterPreferenceReadWriteLock
();



pointcut
readMethod
() :


execution(* MyResource.*(..)) && !
writeMethod
();


pointcut
writeMethod
() :


execution(*
MyResource.update
*(..));


Example:
Multiple Readers, Single Writer Aspect used a
perthis

aspect
instantiation model


before() :
readMethod
() {


try {


rw.readLock
().acquire();


} catch (
InterruptedException

intEx
) {


throw new
RuntimeException
("Unable to obtain R lock");


}


}


after() :
readMethod
() {


rw.readLock
().release();


}


before() :
writeMethod
() {


try {


rw.writeLock
().acquire();


} catch (
InterruptedException

intEx
) {


throw new
RuntimeException
("Unable to obtain W lock");


}


}


after() :
writeMethod
() {


rw.writeLock
().release();


}


declare warning:
readMethod
() &&
writeMethod
() :


"A method cannot be both a read and a write method";

}


Example:
Multiple Readers, Single Writer Aspect used a
perthis

aspect
instantiation model (continued)

Aspect Inheritance


Just as we can define hierarchies of classes,
we can define hierarchies of aspects.



Aspects can extend classes, implement
interfaces, and even extend other aspects.


Classes may not extend aspects, however.


Aspect inheritance is more restricted than class
inheritance

Aspect Inheritance

You can only extend an abstract aspect; that is,
only "leaf" aspects can be concrete. In addition,
aspects must be declared public if they are to be
extended by aspects in another package.

Aspect Inheritance


Extending Aspects


An abstract aspect enables you to define the shape of a solution to a
problem, but leave the details that will vary from case to case to be
provided by a concrete sub
-
aspect.



When one aspect extends another, it inherit any fields, methods, pointcuts
and advice.



A sub
-
aspect can also define its own instantiation model (singleton, perthis,
and so forth)


Example:
a sub
-
aspect may use a perthis instantiation model

public abstract aspect AbstractSingletonAspect {


...

}

public aspect PerthisConcreteAspect


extends AbstractSingletonAspect perthis(...){


...

}

Inner Aspects


An aspect can be defined within the scope of a
class, an interface, or another aspect.


The only restriction is that it must be declared
as static.


This is because non
-
static inner types have their
own instantiation model which is incompatible
with that used by aspects.


Inner aspects are typically used to capture
concerns that crosscut a single class.

Inner Aspects

public class
MyResource

{ private static aspect Synchronization


extends
MultipleReadersSingleWriter

{


protected pointcut
readMethod
() :


execution(* MyResource.*(..)) && !
writeMethod
();



protected pointcut
writeMethod
() :


execution(*
MyResource.update
*(..));


}


private Integer a;


private Integer b;


public
MyResource
() {


a = new Integer(
100
);


b = new Integer(
200
);


}


public Integer
getA
() { return a; }


public Integer
getB
() { return b; }


public void
updateAandB
(Integer a, Integer b) {


this.a

= a;


this.b

= b;


}

}


Using an Inner Aspect to
Protect MyResource

Examples (run in AspectJ under eclipse)


Join Points and
thisJoinPoint


The code for this example is in
InstallDir
/examples/tjp


It is about gathering and using information about the join
point that has triggered some advice.


Roles and Views


The code for this example is in
InstallDir
/examples/introduction


It provides three illustrations of the use of inter
-
type
declarations to encapsulate roles or views of a class.


cloneable, hashable, and comparable

Demo


Our programming setup


Eclipse
3.4
Ganymede


AJDT plugin that provides AspectJ facilities under
eclipse.


Examples:


Hello World aspect


TJP aspect

References


Ivar Jacobson and Pan
-
wie Ng. Aspect
-
Oriented software
Development with Use Cases.
2005
Addison
-
Wisely.


Robert

E.

Filman, Tzilla

Elrad, Siobhán

Clarke, Mehmet

Aksit.
Aspect
-
Oriented Software Development.
Addison Wesley
Professional
2005
.


Adrian

Colyer, Andy

Clement, George

Harley,
Matthew

Webster.
Eclipse AspectJ: Aspect
-
Oriented
Programming with AspectJ and the Eclipse AspectJ
Development Tools.
Addison Wesley Professional Pub.
December
2004
.


Ramnivas Laddad. I Want my AOP!, Part I , Part II and Part
3
.
JavaWorld. See:
http://www.javaworld.com/javaworld/jw
-
01
-
2002
/jw
-
0118
-
aspect.html