Hi,
maybe the question is a bit silly but I would like to test/check that all the
implementations of a specific service interface receive a method advice X.
I would like to advise only the update method defined by the ServiceUpdater
interface, so I wrote the following code in my application module:
@Advise(serviceInterface = ServiceUpdater.class)
@Match("*")
public static void useServiceUpdaterCache(MethodAdviceReceiver receiver,
final ServiceUpdaterCache cache) {
MethodAdvice advice = new MethodAdvice() {
@Override
public void advise(MethodInvocation invocation) {
if (cache.isValid()) {
cache.updateService((DynamicServiceDescription) invocation.getParameter(0));
} else {
invocation.proceed();
cache.store((DynamicServiceDescription)
invocation.getParameter(0));
}
}
};
// Advice only the actuate method
System.out.println("Receiver interface: "
+ receiver.getInterface().getName());
for (Method m : receiver.getInterface().getMethods()) {
System.out.println("Processing " + m.getName());
if ("update".equals(m.getName())) {
System.out.println("\n\nAdvising: " +
m.getName());
receiver.adviseMethod(m, advice);
}
}
};
But as output I got the list of all the services that invoked:
Receiver interface: java.lang.Runnable
Processing run
Receiver interface: org.apache.tapestry5.ioc.services.SymbolSource
Processing expandSymbols
Processing valueForSymbol
Receiver interface: org.apache.tapestry5.ioc.services.SymbolProvider
Processing valueForSymbol
Receiver interface: org.apache.tapestry5.ioc.services.TypeCoercer
Processing clearCache
Processing coerce
Processing getCoercion
Processing explain
...
I guess that this behavior can be explained with the use of @Match("*"), but
what about @Advice with the serviceInterface ? Is it ignored ?
At the moment, the ServiceUpdater interface is implemented only by one class,
i.e., ServiceUpdaterImpl, but in the module I have two build* methods that have
different dependencies injected:
public static ServiceUpdater buildOSServiceUpdater(Logger logger,
@InjectService("OpenStackTypica") CloudInterface cloudInterface) {
return new ServiceUpdaterImpl(logger, cloudInterface);
}
public static ServiceUpdater buildAmazonServiceUpdater(Logger logger,
@InjectService("AmazonTypica") CloudInterface cloudInterface) {
return new ServiceUpdaterImpl(logger, cloudInterface);
}
I know I can refine the condition inside the @Match annotation to something
like "*ServiceUpdater" but I prefer to use the ServiceInterface.class as
"filter".
Eventually I would like adviseAll the serviceUpdater interface methods, instead
of using the (non-refactoring-safe) method name to identify the receiver.
Can someone shed some light here ? Is that a bug ? a misuse of the annotations
?
Thanks
-- Alessio