Advice is a block of codes which will be inserted into another
program. This could be called Interceptor.
Joinpoint(MethodInvocation)
Joinpoint is a point which Advice will be associated with a targeted
class. Advice is allowed to get information about a method name and arguments from Joinpoint.
Pointcut
Pointcut is used to define the point where Jopinpoint is set in.
AOP offers you a better maintenance by separating a "Core Concern"
and a "Crosscutting Concern".
Your source code will be simple by detaching a systematic feature
from a business logic. The detached systematic feature becomes a "Core
Concern" in a "Croscutting Concern". As a result, your source code will be
responsible only for your purpose.
You don't need complicated procedures such as an automatic
transaction management or a remote method invocation made by EJB
anymore. You can do it by POJO(Plain Old Java Object: POJO is an object
indepented from a specific Java API.)
Required interface implementations will be reduced to only one.
An aspect applied to the component can be cleared.
S2AOP enables you to start AOP programmings immediately since
common implementations of object patterns for Aspect are provided. (You
are allowd to implement your own interfaces and abstract classe.)
You can't adopt an aspect to a final method, a static method and a non-public method.
If you don't set a pointcut attribute, some methods will not accept
an aspect. In order to make every method to accept an aspect, you must set
".*" to a pointcut attribute.
You need a configuration file (known as "dicon file") for
S2Container to use S2AOP. However, you can place a configuration file
in any directory, a configuration file is commonly created in
the same directory(a.k.a. folder) as the "Crosscutting Concern" or the
targeted component resides.
An aspect tag is used to associate an aspect with a component. Write
the Interceptor configuration in the body by using the OGNL expression or
in the nested tag accompanied by the component tag.
* Please refer below for OGNL OGNL
Language Guide
What will happen if you associate multiple aspects with one component ?
Aspects will be invoked according to the order which they are
defined in a configuration file. If you want to know more, please
read Original Interceptor for futher
information
Pay attention
The component specified by the aspect tag will be get through the container
while its initialization processes are going on. This indicates that a new
instance doesn't create everytime when an Interceptor method is invoked
under the condition that an instance attribute of a component is assigned as a
prototype.
pointcut attribute(optional)
You can specify multiple method names delimited by commmas. If you
don't set any pointcut, all implemented methods in a component will be
invoked. You can use the regular expression(JDK1.4 regex) to specify
method names.
Configuration Example
Suppose you want to set the aspect in both getTime() method and
hasCode() method of java.util.Date class by means of a pointcut attribute,
then the configuration will be as follows.
This Interceptor handles a trace as a "Crosscutting Concern". Dicon
file shown below is an example that TraceInterceptor is applied to
getTime() method of java.uitl.Date class.
This Interceptor handles an exception as a "Crosscutting
Concern". Implement the method "Object handleThrowable(Throwable,
MethodInvocation)" in your class inherited from ThrowsInterceptor before
you use this. You can assign a subclass of java.lang.Throwable to the
first parameter of this method. If you define the method "Object
handleThrowable(IOException, MethodInvocation)", the exception will
be caught by the object which type is IOException or the subclass of
IOException when the excpetion raised in the component associated with
ThrowsInterceptor. You are allowed to define multiple handleThrowable()
methods. Please read ThrowsInterceptor for further
information.
This Interceptor delegates a method invocation to another
component. A delegation is performed when a component is assigned to
a target property of DelegateInterceptor. If you want to specify a
method name explicitly to support different method names, use
"DelegateInterceptor#addMethodNameMap(String methodName, String
targetMethodName)". Suppose you want to let the method bar() be delegated
to foo.bar2(), then your code might be like this: "DelegateInterceptor#setTarget(foo),DelegateInterceptor#addMethodNameMap("bar", "bar2")". Please read DelegateInterceptor for further information.
Pay attention
A component assigned to a target property will be get through the
container while its initialization processes are going on. As a result, the
same instance will be used even if the instance attribute of the component is
a property. If you want to get a new instance for every method invocation,
use PrototypeDelegateInterceptor described below.
This Interceptor delegates a method invocation to another
component. A new component will be get from a container in every
method invocation. The delegation is performed when the targeted component
name is assigned to the targetName property of
PrototypeDelegateInterceptor. If you want to set a method name explicitly
to support different method names, use
"PrototypeDelegateInterceptor#setTarget(foo),
PrototypeDelegateInterceptor#addMethodNameMap("bar", "bar2")". Please read PrototypeDelegateInterceptor
for further information.
This Interceptor synchronizes a multiple method invocations by
an aspect. You don't need to modify your code when you want to sychronize
method invocations. Please read SyncInterceptor for further information.
This Interceptor enables you to combine multiple Interceptors and to
reuse them easily. If you want to adopt a combination to more than one
component, give the name of InterceptorChain into each component as follows.
The invoke() method shown below is the only one that you have to
implement in both cases.
public Object invoke(MethodInvocation invocation) throws Throwable
AbstractInterceptor is an abstract class and implements
MethodInterceptor. AbstracInterceptor has two methods, createProxy() and
getTargetClass() shown below. createProxy() method is used to get
a Proxy object. getTargetClass() method is used to get a target
class which an aspect is associated. When Interceptor requires a name of
a class that an aspect is associated with, for example, logging
Interceptor, you can get a required class name easily from
AbstractInterceptor.
public Object createProxy(Class proxyClass)
protected Class getTargetClass(MethodInvocation invocation)
You can get a target object, method and arguments from
MethodInvocation object given as a parameter of getTargetClass()
method. getThis() method has a feature to get a class name from a
bytecode. proceed() method invokes a concrete method and gets the result
through this invocation. Following is an example how to use proceed()
method.
Example
public class ABS implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Before");
Object ret = invocation/proceed();
System.out.println("After");
return ret;
}
}
This example consists of two parts, before and after the proceed()
method. The first part is ensured to be executed before proceed()
method and the second part is ensured to be done after proceed()
method. Suppose multiple aspects associated with only one component,
then aspects will be invoked as follows:
An execution goes down along the order of aspect elements
appeared in dicon file. At this stage, codes reside in former part of
proceed() method of MethodInterceptor are executed.
After the last execution has done, methods in a component are invoked next.
An execution goes up along the reverse order of aspect elements
appered in dicon file. At this state, codes reside in latter part of
proceed() method of MethodInterceptor are executed.
This section describes how to put aspects into your program without
dicon file. Four solutions shown below are provided.
Assign one or more method names to arguments of
org.seasar.framework.aop.impl.PointcutImpl constructor. Suppose a class
implements some interfaces, all methods in an interface can be associated
with an aspect. For example, when you emply java.util.HashMap and write
your code like new PointcutImpl(HashMap.class), all methods in
java.util.Map interface can be associated with an aspect automatically.
Set Interceptor to the first argument and Pointcut to the second
argument of org.seasar.framework.aop.impl.AspectImpl constructor. You need
to create this Pointcut from PointcutImpl.
Set the target class and an array of Aspect to arguments of
org.seasar.framework.aop.proxy.AopProxy constructor. You need to create
this Aspect from AspectImple.
You can get an object which is associated with Aspect from a
method, org.seasar.framework.aop.proxy.AopProxy#create()
This is an example how to insert an aspect without dicon file. This
example adopts TraceInterceptor to java.uitl.Date, and let getTime()
method be a target method.
Pointcut pointcut = new PointcutImpl(new String[]{"getTime"});
Aspect aspect = new AspectImpl(new TraceInterceptor(), pointcut);
AopProxy aopProxy = new AopProxy(Date.class, new Aspect[]{aspect});
Date proxy = (Date) aopProxy.create();
proxy.getTime();
First example uses TraceInterceptor. This shows you how to output a
trace when getTime() and hasCode() methods in both java.util.Array and
java.util.Date classes are invoked. Write two files explained below.
Dicon file to define a component(Trace.icon)
Java class to check whether the configuration is defined correcltly or not(AopTraceClient.java)
How to write dicon file
Define a component element for TraceInterceptor. In
this case, name attribute is "traceInterceptor".
Define a component element for java.util.ArrayList
class. Add an aspect element as a nested child element of component and set
the name "traceInterceptor" in its body.
Define a component element for java.util.Date
class. Likewise, add an aspect element and set "traceInterceptor" to its
body. This time, set both getTime() and hashCode() methods to a pointcut
attribute of an aspect element. In addition, define an arg element to pass
a value of zero to java.util.Date constructor.
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(Trace.dicon) to an argument of create() method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign List.class and
java.util.Date to the arguments of each getComponent() method.
Inovke one of methods ArrayList component has. This
example choose size() method. Check that the trace captured by an aspect
while the method is executing.
Equally, invoke getTime() and hasCode() methods of
Date component and check the trace.
AopTraceClient.java
package examples.aop.traceinterceptor;
import java.util.Date;
import java.util.List;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class AopTraceClient {
private static String PATH = "examples/aop/traceinterceptor/Trace.dicon";
public static void main(String[] args) {
S2Container container = S2ContainerFactory.create(PATH);
ArrayList list = (List) container.getComponent(ArrayList.class);
list.size();
Date date = (Date) container.getComponent(Date.class);
date.getTime();
date.hashCode();
}
}
Output
You see an output shown below. This means that the traces are
outputed both before and after the method invocation. As for Date
component, you know java.util.Date#getTime() method is traced between
BEGIN and END of hasCode() method, too. The reason is that getTime()
method is used in hashCode() method.
BEGIN java.util.ArrayList#size()
END java.util.ArrayList#size() : 0
BEGIN java.util.Date#getTime()
END java.util.Date#getTime() : 0
BEGIN java.util.Date#hashCode()
BEGIN java.util.Date#getTime()
END java.util.Date#getTime() : 0
END java.util.Date#hashCode() : 0
This example is included in the directory, seasar2/src/examples/aop/traceinterceptor.
(1)The second example uses ThrowsInterceptor. This shows you how to
go processing through to the end even if an exception occurs. Write four
files explained below.
A class that raises RuntimeException(Checker.java)
Interceptor inherited from ThrowsInterceptor(HandleThrowableInterceptor.java)
Dicon file to define a component(Checker.dicon)
Java class to check whether the configuration is
made correctly or not(AopCheckerClient.java)
How to define a class that throws exception
This class outputs a string given as an argument
when a string is not null.
This class throws NullPointerException when null is
set to an argument of check() method.
Checker.java
package examples.aop.throwsinterceptor;
public class Checker {
public void check(String str) {
if (str != null) {
System.out.println(str);
} else {
throw new NullPointerException("null");
}
}
}
How to define Interceptor inherited from ThrowsInterceptor
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(Checker.dicon) to an argument of create() method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign Foo.class.
Pass the string "foo" to Checker#check()
method as an argument
Raise an exception by passing null to an argument of
Checker#check() method.
Pass the second string "hoge" to
Checker#check() method as an argument.
You see the string "hoge", so you know that the raised
exception didn't stop processing.
foo
hoge
This example is included in seasar2/src/examples/aop/throwsinterceptor
(2) This ThrowsInterceptor example shows you how to replace the type
of exeception with another Interceptor. Modify HandleThrowableInterceptor
defined above.
How to make Interceptor to throw a new exception
Suppose org.seasar.framework.exception.SRuntimeException will be thrown
when the first argument of handleThrowable(Throwable, MethodInvocation)
method is NullPointerException, then you need to modify
HandleThrowableInterceptor as follows.
package examples.aop.throwsinterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.ThrowsInterceptor;
import org.seasar.framework.exception.SRuntimeException;
public class HandleThrowableInterceptor extends ThrowsInterceptor {
public void handleThrowable(NullPointerException t, MethodInvocation invocation)
throws Throwable {
throw new SRuntimeException("ESSR0007", new Object[] { "argument" });
}
}
You use other three files, Checker.java, Checker.dicon and
AopCheckerClient.java, to run this example.
Output
You see new error messages shown below.
foo
Exception in thread "main" org.seasar.framework.exception.SRuntimeException:
[ESSR0007]argument should not be null or empty
at examples.aop.throwsinterceptor.HandleThrowableInterceptor.handleThrowable(
HandleThrowableInterceptor.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(
DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.seasar.framework.aop.interceptors.ThrowsInterceptor.invoke(
ThrowsInterceptor.java:54)
at examples.aop.throwsinterceptor.Checker$$EnhancedByS2AOP$$16672d6$$
MethodInvocation$$check0.proceed(MethodInvocationClassGenerator.java)
at examples.aop.throwsinterceptor.Checker$$EnhancedByS2AOP$$16672d6.check(
Checker$$EnhancedByS2AOP$$16672d6.java)
at examples.aop.throwsinterceptor.AopCheckerClient.main(AopCheckerClient.java:13)
This example is included in seasar2/src/examples/aop/throwsinterceptor
The third example uses DelegateInterceptor of S2AOP. This shows how to
delegate a method invocation to another class's method invocation.
First, define an abstract method in the interface, IBase.java. Next,
define one abatract class, Dummy.java and one concreate class,
Substance.java to implement IBase interface. Then, you are ready to
delegate a method invocation in an abstract class to a concrete
class. Write five files explained below.
An interface(IBase.java)
An abstract class that implmenets IBase interface(Dummy.java)
A concreate class that implements IBase interface.(Substance.java)
A dicon file so that the method invocation
can be delegated.(Delegate.dicon)
Java class to check whether the configuration is
made correctly or not(AopDelegateClient.java).
An interface, IBase.java
Define an interface so that it has an abstract method.
IBase.java
package examples.aop.delegateinterceptor;
public interface IBase {
public abstract void run();
}
An abstract class, Dummy.java
Implement the interface defined above.
Dummy.java
package examples.aop.delegateinterceptor;
public abstract class Dummy implements IBase {
}
A concrete class, Substance.java
Implement the interface defined above.
Implement the abstract method defined above.
Substance.java
package examples.aop.delegateinterceptor;
public class Substance implements IBase {
public void run() {
System.out.println("substance");
}
}
Dicon file
Define a component element for the abstract class,
Dummy
Define an aspect element to associate Dummy with
DelegateInterceptor component. Within this component element, define
initMethod element to specify target component so that
DelegateInterceptor#setTarget() delegates a method invocation to a
target component. As shown below, the target component,
examples.aop.delegateinterceptor.Substance, is set by a method injection.
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(Delegate.dicon) to an argument of create() method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign IBase.class.
Invoke IBase#run() method in the component got from
a container.
AopDelegateCilent.dicon
package examples.aop.delegateinterceptor;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class AopDelegateClient {
private static String PATH = "examples/aop/delegateinterceptor/Delegate.dicon";
public static void main( String[] args ){
S2Container container = S2ContainerFactory.create(PATH);
IBase base = (IBase) container.getComponent(Dummy.class);
base.run();
}
}
Output
The output string "substance" will appear on a console, so
you can check that Dummy#run() has been delegated to Substance#run()
substance
This example is included in seasar2/src/examples/aop/delegateinterceptor
This example uses PrototypeDelegateInterceptor and delegates from
a singlton component to a prototype component.
To make this example, first, define an abstract method in an intarface,
then define an abstract class(singleton) and a concrete class(prototype)
so that these two classes implement the interface. Second, write dicon
file so that the method invocation of the abstract class will be delegated
to the method in the concrete class. Write four files described below.
An interface(IBase.java)
An abstract singleton class that implements the interface(Dummy.java)
A prototype class that implements the interface(Substance.java)
Dicon file to deinfe a delegation(Delegate.dicon)
Java class to check whether the configuration is made correctly or not(AopPrototypeDelegateClient.java)
An interface, IBase.java
Define a abstract method.
IBase.java
package examples.aop.delegateinterceptor;
public interface IBase {
public abstract void run();
}
An abstract class that implements the interface, Dummy.java
Implement the interface defined above.
Dummy.java
package examples.aop.delegateinterceptor;
public abstract class Dummy implements IBase {
}
A concrete class that implements the interface, Substance.java
Implement the interface defined above.
Implement the abstract method defined in the interface.
Substance.java
package examples.aop.delegateinterceptor;
public class Substance implements IBase {
public void run() {
System.out.println(this);
}
}
Dicon file
Define a component element for an abstract class,
Dummy. This component is a singleton.
Define an aspect element for the component,
PrototypeDelegateInterceptor. Within this component element, define a
property element to specify the target name ("target") to the
property, targetName.
In addition, define a component element for a target
class, Substance. An instance attribute of this component is a
prototype.
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(PrototypeDelegate.dicon) to an argument of create()
method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign IBase.class.
Invoke IBase#run() method in the component got from
a container several times.
AopPrototypeDelegateCilent.dicon
package examples.aop.prototypedelegateinterceptor;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class AopDelegateClient {
private static String PATH =
"examples/aop/prototypedelegateinterceptor/PrototypeDelegate.dicon";
public static void main( String[] args ){
S2Container container = S2ContainerFactory.create(PATH);
IBase base = (IBase) container.getComponent(Dummy.class);
for (int i = 0; i < 5; ++i) {
base.run();
}
}
}
Output
The output strings such as
"examples.aop.prototypedelegateinterceptor.Substance@xxxxxx"
will appear on a console, so you can check that Dummy#run() has been
delegated to Substance#run(). Besides, you know that new Substance
instances are created in every run() method invocation because output
strings contain "@" followed by a hashcode value.
This example uses SyncInterceptor to be able to synchronize accessing
to one object from multiple threads.
For the comparison with SyncInterceptor and without it, we make a example
without SyncInterceptor. First example creates multiple threads to access
to a shared object. A shared object provides a method that adds one to
the counter. Wrtie four files described below.
An interface that has a method to add one to the counter.(Count.java)
A conrete class that implements an interface(CountImpl.java)
Dicon file that defines components(SyncCalc.dicon)
Java class to check whether the configuration is defined correcltly or not(AopSyncClient.java)
An interface, Count.java
Define a method to add one to a counter
Define another method to get a counter value.
Count.java
package examples.aop.syncinterceptor;
public interface Count {
public void add();
public int get();
}
A concrete class, CountImple.java
Implement the interface defined above.
Declare counter variable and assign an initial value
of zero.
Implement add() method so that it adds one to counter
after sleeps for two seconds. The value before the addition is diplayed, too.
Implement get() method so that it returns the
counter value.
CountImpl.java
package examples.aop.syncinterceptor;
public class CountImpl implements Count {
private int _count = 0;
public void add() {
int a = _count;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
_count = a + 1;
System.out.println(a);
}
public int get() {
return _count;
}
}
Dicon file
Define a component element for CountImple created above.
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(SyncCalc.dicon) to an argument of create()
method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign Count.class.
Create new Runnable instance. This instance is run
by a thread and invokes add() method in Count class.
Create five Thread instances
Invoke each Thread#start() method so that five
threads can work.
Invoke Thread#join() method to wait all of other
threads finish thier works.
Output counter value when all created threads have
done thier work.
AopSyncClient.java
package examples.aop.syncinterceptor;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class AopSyncClient {
private String PATH = "examples/aop/syncinterceptor/SyncCalc.dicon";
private Count _count = null;
public void init() {
S2Container container = S2ContainerFactory.create(PATH);
_count = (Count) container.getComponent(Count.class);
}
public void start() {
System.out.println("count: " + _count.get());
Runnable r = new Runnable() {
public void run() {
_count.add();
}
};
Thread[] thres = new Thread[5];
for (int i=0; i<5; i++) {
thres[i] = new Thread(r);
thres[i].start();
}
for (int i=0; i<5; i++) {
try {
thres[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("count: " + _count.get());
}
public static void main(String[] args) {
AopSyncClient asc = new AopSyncClient();
asc.init();
asc.start();
}
}
Output
This output shows that created threads aren't synchronized.
count: 0
0
0
0
0
0
count: 1
Next, redefine dicon file to make created threads to synchronize by SyncInterceptor.
This section describes how you can make your own Interceptor. To help
you to understand well, we adopt one example that get a target class name,
method name and arguments. Besides, this example measures processing times
needed in each method invocations. Also, we try to keep track a processing
time that extremly consumes cpu power by our Interceptor. Write four files
shown below.
An Interceptor that outputs a target class name,
method name and arguments. Also, this outputs a method processing time
measured by this Interceptor.(MeasurementInterceptor.java)
A class which will be associated with
Interceptor. Write this class so that consumes much cpu
power.(HeavyProcess.java)
Dicon file that defines components.(Measurement.dicon)
Java class to check whether the configuration is defined correcltly or not.(AopMeasurementClient.java)
Get FQCN(Fully Qualified Class Name) of a target
class through getTargetClass(invocation).getName() method. If you get a
name from MethodInvocation#getThis() method, you'll be get an embeded
class name in bytecode.
Get the method name through
invocation.getMethod().getName() method.
Get arguments through invocation.getArguments() method.
Get the current time before invocation.proceed()
method. This means that you get the time just before the method invocation
because invocation.proceed() invokes a target method.
Get the current time again after
invocation.proceed() method. This has an effect to get the time right
after the real method invocation. Then, output the processing time in a
finally clause.
MeasurementInterceptor.java
package examples.aop.originalinterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;
public class MeasurementInterceptor extends AbstractInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
long start = 0;
long end = 0;
StringBuffer buf = new StringBuffer(100);
buf.append(getTargetClass(invocation).getName());
buf.append("#");
buf.append(invocation.getMethod().getName());
buf.append("(");
Object[] args = invocation.getArguments();
if (args != null && args.length > 0) {
for (int i = 0; i < args.length; ++i) {
buf.append(args[i]);
buf.append(", ");
}
buf.setLength(buf.length() - 2);
}
buf.append(")");
try {
start = System.currentTimeMillis();
Object ret = invocation.proceed();
end = System.currentTimeMillis();
buf.append(" : ");
return ret;
} catch (Throwable t) {
buf.append(" Throwable:");
buf.append(t);
throw t;
} finally {
System.out.println(buf.toString() + (end - start));
}
}
}
How to wrtie a class that will be associated with Interceptor
Make this class to sleep five seconds because we
want to assume this class consumes much cpu power.
HeavyProcess.java
package examples.aop.originalinterceptor;
public class HeavyProcess {
public void heavy(){
try{
Thread.sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
Dicon file
Define a component element for
MeasurementInterceptor. Assign measurement to name attribute.
Define a component element for HeavyProcess class and
define an aspect element as a nested element to associated heavy() method
with MeasurementInterceptor.
Create a S2Container object by the method,
org.seasar.framework.container.S2ContainerFactory#create(). Set a path
to dicon file(Measurement.dicon) to an argument of create()
method.
Get an object by the method,
org.seasar.framework.container.S2Container#getComponent(). Set a component
name to an argument of getComponent() method. A component name must be
the name defined in dicon file. In this case, assign
HeavyProcess.class.
Invoke HeavyProcess#heavy() method got from a
container.