Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] writing around advice for an unknown method

> So obviously we are extracting more information than just the arguments (for
> example, using a target() pointcut) which cannot be passed to the advised
> method as it would not be defined to accept our context (in this case a
> target object).

No it cannot be passed to the advised method but it can be used to
modify the target of the proceed()

public aspect Foobar {
	public static void main(String[] args) {
		new Foo().run();
	}
	
}

class Foo {
	
	public void run() {
		System.out.println("running on instance "+this);
	}
}

aspect X {
	void around(Foo instance): call(* run(..)) && target(instance) {
		System.out.println("Intercepting call to "+instance);
		proceed(new Foo());
	}
}

run it:
Intercepting call to Foo@93dcd
running on instance Foo@b89838



On 21 March 2010 22:28, Ashank <k_arvind_shankar@xxxxxxxxx> wrote:
>
> Hello Hermann,
>
> Thanks for the answers and the interesting post script.
>
> However, I still do not understand why the proceed() call and the 'around()
> advice' HAVE to have the same arguments. I know from a brief test that this
> is indeed the case but I can't understand why. One of the advantages of
> pointcuts and advices is the ability to get the context from the joinpoints
> along with the method arguments (in case of call/execution pointcut). So
> obviously we are extracting more information than just the arguments (for
> example, using a target() pointcut) which cannot be passed to the advised
> method as it would not be defined to accept our context (in this case a
> target object).
>
> Also, I briefly tested, by advising a setter/getter method pair, that even
> if one is not getting the arguments explicitly using the args() pointcut,
> the args will still be passed on to the proceed() call (with no arguments)
> in the around advice (also with no arguments) which is convenient but not
> intuitive. Thoughts?
>
> Also, if I may ask, why an extinct prehistoric 'amphibian' like ictheostega
> and not something like one of those fishes from the '7 deadliest seas'
> documentary
>
> -Arvind
>
>
>
> Ichthyostega wrote:
>>
>> Arvind Krishnaswamy schrieb:
>>> I have an urgent 'newbie' question and could not get the info from the
>>> docs
>>> and forums upon a brief search. I am confused about the around advice and
>>> calling proceed from within it.
>>
>>> I want to write an 'around' advice for a random method call (e.g. the
>>> pointcut call(* *(..)). For such pointcuts, I don't know about the
>>> matching
>>> method call and its return type. For instance, the method might return
>>> nothing (void) or a primitive or an object. How do I write the 'proceed'
>>> statement in this case?
>>
>>
>> Hello Arvind,
>>
>> the "proceed(..)" mirrors the signature of your around advice.
>> You can consider advice as being a java method, and the simple
>> check is that the around advice must be able to stand in place
>> of the proceed, which is like a method invocation.
>>
>> Thus, if you're advising a pointcut which provides parameters,
>> then obviously your advice needs to accept compatible parameters
>> and so does the embedded proceed(..)
>> In your case, the pointcut doesn't provide arguments and thus
>> your around advice has no parameters. Thus, the proceed is
>> no-arg.
>>
>> Regarding the return value, I'm not completely sure. I know that
>> there's some autoboxing in place, thus you'll e.g. get an
>> java.lang.Integer, even if the advised entity returns an int.
>> If I recall correct (please just try it out!), if the proceed()
>> *might* return a value, then you'll get an object, which can
>> be null (and will be if there isn't a return value).
>>
>> hope that helps
>> Hermann V.
>>
>>
>> PS: there is an not-so obvious consequence of this parameter
>> handling with around: If your pointcut picks up the *target*
>> of a call and exposes this target as a *parameter*, then you're
>> indeed able to *exchange* the target object with another object
>> instance of compatible type within the around advice. In this
>> special case, according to the reasoning given above, you have
>> to supply either the original or an exchanged call target as an
>> *parameter* to proceed. That's an incredibly useful feature,
>> both for injecting testcode as well as for abstracting services.
>>
>>
>>
>>
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>>
>
> --
> View this message in context: http://old.nabble.com/adding-local-variables-using-aspect-J-tp27893938p27982528.html
> Sent from the AspectJ - users mailing list archive at Nabble.com.
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>


Back to the top