SPRING-SOURCE.RU

Advice

Когда мы прицепились, то нужно, что-то выполнить, какие-то действия. Действия – это и есть advice. Advice бывают разных типов. В примере приведен один из типов Advice – before.

                        
pointcut setter (Point p1, int newval) :
	target (p1) && args (newval) &&
	(call (void setX(int) || call (void setY(int)));

before (Point p1, int newval): setter (p1, newval)
{
	System.out.println("Setting in " + p1 + " to the new value " + newval);
}
		

Здесь before – это advice. Target является класс Point, arg-ом является один int и цепляемся на вызов методов setX и setY.

Когда у нас taget является класс Point, когда у нас аргументом является один integer и когда мы цепляемся на вызов метода setX или вызов метода setY. По сути это метод, который цепляется на setter либо X, либо Y (сеттеры класса Point).

В этом примере передаются параметры. В методах мы указываем сигнатуру без параметров, а в специальном ключевом слове args указываем имена этих параметров, которые передаем в название pointcut-а и, потом, в before тоже указываю эти параметры.

Advice бывает следующих видов:

Действия перед выполнением метода:

                        
before (Point p, int x): target(p) && args(x) && call (void setX(int)) {
	if (!p.assertX(x)) return;
}
		

После вызова метода, независимо от того, как метод вернул управление:

                        
after (Point p, int x): target(p) && args(x) && call (void setX(int)) {
	if (!p.assertX(x)) throw new PostConditionViolation();
}
		

После вызова метода, если только он вернул управление нормально:

                        
after (Point p) returning (int x): target(p) && call (int getX()) {
	System.out.println("Returning int value " + x + " for p = " + p);
}
		

После вызова метода, который вернул управление через исключение:

                        
after () throwing (Exception e): target(Point) && call (void setX(int)) {
	System.out.println(e);
}
		

Выполнение кода вместо метода. Конструкция proceed позволяет войти в метод:

                        
around (Point p, int x): target(p) && args(x) && call (void setX(int)) {
	if (p.assertX(x))
	proceed (p, x);
	p.releaseResources();
}