Aspectj: метод перехвата из внешней банки

Я использую X.jar и добавляю к моему проекту AspectJ (в eclipse). Я написал pointcut и совет для метода myMethod() внутри X.jar.

Но aspectj не перехватывает вызов этого метода.

Как я могу передать aspectj для перехвата вызовов метода на внешних баночках. Или это невозможно?

Спасибо

Ответ 1

Есть два варианта:

a) скомпилируйте аспекты в JAR
б) использовать время загрузки во времени (я бы пошел с этим)

Оба эти являются расширенными темами, я бы предложил вам прочитать AspectJ в действии (2-е изд.) Рамниваса Лэддада, чтобы узнать больше.

Чтобы уточнить: существуют различные типы pointcut. Если ваш код вызывает методы библиотеки, вы можете, конечно, перехватить эти вызовы, как это происходит в вашем коде. Таким образом, pointtuts call() будут работать, но execute() (и многие другие) pointcut не будут, потому что они меняют метод выполнения, который не находится в вашей базе кода. Поэтому вам нужно либо изменить байтовый код библиотеки (опция a), либо изменить способ ее загрузки в ваше приложение (вариант b).

Ответ 2

Вот простой пример с AspectJ Load-Time Weaving на GitHub https://github.com/medvedev1088/aspectj-ltw-example

Он использует библиотеку времени Joda, чтобы продемонстрировать, как перехватить вызовы метода DateTime # toString().

Аспект:

@Aspect
public class DateTimeToStringAspect {

    public static final String TO_STRING_RESULT = "test";

    @Pointcut("execution(* org.joda.time.base.AbstractDateTime.toString())")
    public void dateTimeToString() {
    }

    @Around("dateTimeToString()")
    public Object toLowerCase(ProceedingJoinPoint joinPoint) throws Throwable {
        Object ignoredToStringResult = joinPoint.proceed();
        System.out.println("DateTime#toString() has been invoked: " + ignoredToStringResult);
        return TO_STRING_RESULT;
    }
}

aop.xml

<aspectj>

    <aspects>
        <!-- Aspects -->
        <aspect name="com.example.aspectj.DateTimeToStringAspect"/>
    </aspects>

    <weaver options="-verbose -showWeaveInfo">
        <include within="org.joda.time.base.AbstractDateTime"/>
    </weaver>

</aspectj>

Тест:

public class DateTimeToStringAspectTest {
    @Test
    public void testDateTimeToString() throws Exception {
        assertThat(new DateTime().toString(), is(DateTimeToStringAspect.TO_STRING_RESULT));
    }
}

Конфигурация плагина Surefire из pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.9</version>
    <configuration>
        <argLine>-XX:-UseSplitVerifier</argLine>
        <argLine>-javaagent:${user.home}/.m2/repository/org/aspectj/aspectjweaver/${aspectjweaver.version}/aspectjweaver-${aspectjweaver.version}.jar</argLine>
    </configuration>
</plugin>