JavaRush/ΠšΡƒΡ€ΡΡ‹/ΠœΠΎΠ΄ΡƒΠ»ΡŒ 5. Spring/БвязываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ AspectJ Π² Spring

БвязываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ AspectJ Π² Spring

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚Π°

БвязываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ (Load-time weaving/LTW) относится ΠΊ процСссу связывания аспСктов AspectJ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ классов прилоТСния Π²ΠΎ врСмя ΠΈΡ… Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π² Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΌΠ°ΡˆΠΈΠ½Ρƒ Java (Java virtual machin/JVM). Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ основноС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡƒΠ΄Π΅Π»Π΅Π½ΠΎ настройкС ΠΈ использованию ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ контСкстС Spring Framework. Π”Π°Π½Π½Ρ‹ΠΉ Ρ€Π°Π·Π΄Π΅Π» Π½Π΅ являСтся ΠΎΠ±Ρ‰ΠΈΠΌ Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ Π² ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. Для получСния ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ спСцификС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈ Π΅Π³ΠΎ настройкС с использованиСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ AspectJ (ΠΏΡ€ΠΈ этом Spring Π½Π΅ задСйствован Π²ΠΎΠΎΠ±Ρ‰Π΅) см. Ρ€Π°Π·Π΄Π΅Π», посвящСнный ΡΠ²ΡΠ·Ρ‹Π²Π°Π½ΠΈΡŽ Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π² РуководствС ΠΏΠΎ срСдС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ AspectJ.

Π¦Π΅Π½Π½ΠΎΡΡ‚ΡŒ Spring Framework для ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈΠ· AspectJ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ позволяСт Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ процСсс связывания. Π’Π°Π½ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈΠ· AspectJ осущСствляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π³Π΅Π½Ρ‚Π° Java (5+), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π·Π°Π΄Π°Π½ΠΈΠ΅ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΌΠ°ΡˆΠΈΠ½Ρ‹ ΠΏΡ€ΠΈ запускС JVM. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ для всСй JVM, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ…ΠΎΡ€ΠΎΡˆ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ситуациях, Π½ΠΎ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ слишком Π³Ρ€ΡƒΠ±. ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ LTW с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Spring позволяСт Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π½Π° основС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ClassLoader, Ρ‡Ρ‚ΠΎ являСтся Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΡƒΠ΄Π° цСлСсообразнСС Π² срСдС с ΠΎΠ΄Π½ΠΎΠΉ JVM, Π½ΠΎ мноТСством ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ (ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠΉ срСдС сСрвСра ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ).

Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… срСдах эта ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° позволяСт Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ связываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π±Π΅Π· внСсСния ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² сцСнарий запуска сСрвСра ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для добавлСния -javaagent:path/to/aspectjweaver.jar ΠΈΠ»ΠΈ (ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ описано Π΄Π°Π»Π΅Π΅ Π² этом Ρ€Π°Π·Π΄Π΅Π»Π΅) -javaagent:path/to/spring-instrument.jar. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΡƒΡŽΡ‚ контСкст прилоТСния для Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ вмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° администраторов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‚ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ развСртывания, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, скрипты запуска.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ Π½Π°Ρ…Π²Π°Π»ΠΈΠ²Π°Ρ‚ΡŒ, Π΄Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим быстрый ΠΏΡ€ΠΈΠΌΠ΅Ρ€ LTW ΠΈΠ· AspectJ с использованиСм Spring, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ остановимся Π½Π° элСмСнтах, прСдставлСнных Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅.

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΡΠ²Π»ΡΠ΅Ρ‚Π΅ΡΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΏΠΎΡ€ΡƒΡ‡Π΅Π½ΠΎ Π΄ΠΈΠ°Π³Π½ΠΎΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ систСмы. ВмСсто использования инструмСнта профилирования, ΠΌΡ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ простой аспСкт профилирования, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ быстро ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π‘Ρ€Π°Π·Ρƒ послС этого ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΈΠΉ инструмСнт профилирования ΠΊ этой ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ области.

Π’ прСдставлСнном здСсь ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ XML-конфигурация. Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ @AspectJ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Java-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ. Π’ частности, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ @EnableLoadTimeWeaving Π² качСствС Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹ <context:load-time-weaver/>.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ Π½Π΅ слишком Π²Ρ‹Ρ‡ΡƒΡ€Π½Ρ‹ΠΉ аспСкт профилирования. Π­Ρ‚ΠΎ ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ @AspectJ-ΡΡ‚ΠΈΠ»ΡŒ объявлСния аспСктов:

Java
package foo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;
import org.springframework.core.annotation.Order;
@Aspect
public class ProfilingAspect {
    @Around("methodsToBeProfiled()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch sw = new StopWatch(getClass().getSimpleName());
        try {
            sw.start(pjp.getSignature().getName());
            return pjp.proceed();
        } finally {
            sw.stop();
            System.out.println(sw.prettyPrint());
        }
    }
    @Pointcut("execution(public * foo..*.*(..))")
    public void methodsToBeProfiled(){}
}
Kotlin
package foo
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Pointcut
import org.springframework.util.StopWatch
import org.springframework.core.annotation.Order
@Aspect
class ProfilingAspect {
    @Around("methodsToBeProfiled()")
    fun profile(pjp: ProceedingJoinPoint): Any {
        val sw = StopWatch(javaClass.simpleName)
        try {
            sw.start(pjp.getSignature().getName())
            return pjp.proceed()
        } finally {
            sw.stop()
            println(sw.prettyPrint())
        }
    }
    @Pointcut("execution(public * foo..*.*(..))")
    fun methodsToBeProfiled() {
    }
}

Нам Ρ‚Π°ΠΊΠΆΠ΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» META-INF/aop.xml, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ инструмСнту связывания AspectJ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ наш ProfilingAspect с нашими классами. Π”Π°Π½Π½ΠΎΠ΅ соглашСниС ΠΎ Ρ„Π°ΠΉΠ»Π°Ρ…, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° (ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²) Π² ΠΏΡƒΡ‚ΠΈ классов Java ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ META-INF/aop.xml, являСтся стандартом AspectJ. The following example shows the aop.xml file:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <!-- связываСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ классы Π² Π½Π°ΡˆΠΈΡ… ΠΏΠ°ΠΊΠ΅Ρ‚Π°Ρ…, спСцифичных для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ прилоТСния -->
        <include within="foo.*"/>
    </weaver>
    <aspects>
        <!-- связываСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ этот аспСкт... -->
        <aspect name="foo.ProfilingAspect"/>
    </aspects>
</aspectj>

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ части ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, спСцифичной для Spring. Нам Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ LoadTimeWeaver (объяснСниС Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ·ΠΆΠ΅). Π­Ρ‚ΠΎΡ‚ инструмСнт связывания Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ являСтся основным ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΌ Π·Π° связываниС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ аспСктов Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°ΠΉΠ»Π°Ρ… META-INF/aop.xml с классами вашСго прилоТСния. К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, ΠΎΠ½ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ слоТной настройки (Π΅ΡΡ‚ΡŒ Π΅Ρ‰Π΅ нСсколько ΠΎΠΏΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ, Π½ΠΎ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описаны ΠΏΠΎΠ·ΠΆΠ΅), ΠΊΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-слуТба; ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ -->
    <bean id="entitlementCalculationService"
            class="foo.StubEntitlementCalculationService"/>
    <!-- это Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ связываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ -->
    <context:load-time-weaver/>
</beans>

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ (аспСкт, Ρ„Π°ΠΉΠ» META-INF/aop.xml ΠΈ конфигурация Spring) Π½Π° мСстС, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ класс Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€Π° с ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ main(..), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ LTW Π² дСйствии:

Java
package foo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml", Main.class);
        EntitlementCalculationService entitlementCalculationService =
                (EntitlementCalculationService) ctx.getBean("entitlementCalculationService");
        // ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ аспСкт "ΠΎΠΏΠ»Π΅Ρ‚Π°Π΅Ρ‚" Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
        entitlementCalculationService.calculateEntitlement();
    }
}
Kotlin
package foo
import org.springframework.context.support.ClassPathXmlApplicationContext
fun main() {
    val ctx = ClassPathXmlApplicationContext("beans.xml")
    val entitlementCalculationService = ctx.getBean("entitlementCalculationService") as EntitlementCalculationService
    // ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ аспСкт "ΠΎΠΏΠ»Π΅Ρ‚Π°Π΅Ρ‚" Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
    entitlementCalculationService.calculateEntitlement()
}

Нам ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ. Π’ΠΎ Π²Π²Π΅Π΄Π΅Π½ΠΈΠΈ ΠΊ этому Ρ€Π°Π·Π΄Π΅Π»Ρƒ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ, Ρ‡Ρ‚ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Spring ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ LTW Π²Ρ‹Π±ΠΎΡ€ΠΎΡ‡Π½ΠΎ Π½Π° основС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ класса Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ°, ΠΈ это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‚Π°ΠΊ. Однако Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Java-Π°Π³Π΅Π½Ρ‚ (прСдоставляСмый вмСстС со Spring) для Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW. ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ для запуска класса Main, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Ρ€Π°Π½Π΅Π΅:

java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main

Π€Π»Π°Π³ -javaagent – это Ρ„Π»Π°Π³ для задания ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ Π°Π³Π΅Π½Ρ‚ΠΎΠ² для инструмСнтирования ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΡ…ΡΡ Π½Π° JVM. Π’ составС Spring Framework имССтся Ρ‚Π°ΠΊΠΎΠΉ Π°Π³Π΅Π½Ρ‚, InstrumentationSavingAgent, ΡƒΠΏΠ°ΠΊΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π² spring-instrument.jar, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» прСдоставлСн Π² качСствС значСния Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° -javaagent Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅.

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Main выглядит ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅. (Π― Π²Π²Π΅Π» ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ Thread.sleep(..) Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ calculateEntitlement(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ фактичСски зафиксировал ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΡ€ΠΎΠΌΠ΅ 0 миллисСкунд ( 01234 миллисСкунды Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ, Π²Π²ΠΎΠ΄ΠΈΠΌΠΎΠΉ АОП). Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ листингС ΠΏΠΎΠΊΠ°Π·Π°Π½ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ запускС нашСго ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠ°:

Calculating entitlement
StopWatch 'ProfilingAspect': running time (millis) = 1234
------ ----- ----------------------------
ms     %     Task name
------ ----- ----------------------------
01234  100%  calculateEntitlement

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ этот ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ LTW осущСствляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠΎΠ»Π½ΠΎΡ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ AspectJ, ΠΌΡ‹ Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Ρ‹ лишь снабТСниСм совСтами Π±ΠΈΠ½ΠΎΠ² Spring. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ нСбольшая вариация Π½Π° Ρ‚Π΅ΠΌΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Main Π΄Π°Π΅Ρ‚ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

Java
package foo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Main {
    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("beans.xml", Main.class);
        EntitlementCalculationService entitlementCalculationService =
                new StubEntitlementCalculationService();
        // ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ аспСкт Π±ΡƒΠ΄Π΅Ρ‚ "ΠΎΠΏΠ»Π΅Ρ‚Π°Ρ‚ΡŒ" Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
        entitlementCalculationService.calculateEntitlement();
    }
}
Kotlin
package foo
import org.springframework.context.support.ClassPathXmlApplicationContext
fun main(args: Array<String>) {
    ClassPathXmlApplicationContext("beans.xml")
    val entitlementCalculationService = StubEntitlementCalculationService()
    // ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ аспСкт Π±ΡƒΠ΄Π΅Ρ‚ "ΠΎΠΏΠ»Π΅Ρ‚Π°Ρ‚ΡŒ" Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
    entitlementCalculationService.calculateEntitlement()
}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΌΡ‹ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Spring, Π° Π·Π°Ρ‚Π΅ΠΌ создаСм Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр StubEntitlementCalculationService ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π²Π½Π΅ контСкста Spring. ΠŸΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ совСты всС Ρ€Π°Π²Π½ΠΎ ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ΡΡ.

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΏΡ€ΠΈΠΌΠ΅Ρ€ являСтся ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½Ρ‹ΠΌ. Однако, основы ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW Π² Spring Π±Ρ‹Π»ΠΈ прСдставлСны Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΈ Π² ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ части этого Ρ€Π°Π·Π΄Π΅Π»Π° ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описан смысл ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π±ΠΈΡ‚Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ примСнСния.

АспСкт ProfilingAspect, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ, Π½ΠΎ ΠΎΠ½ вСсьма ΠΏΠΎΠ»Π΅Π·Π΅Π½. Π­Ρ‚ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ аспСкта Π½Π° врСмя Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΎ врСмя Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ Π»Π΅Π³ΠΊΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΈΠ· сборок прилоТСния, Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Π² срСдС ΠΏΡ€ΠΈΡ‘ΠΌΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ тСстирования (UAT) ΠΈΠ»ΠΈ эксплуатационной срСдС.

АспСкты

АспСкты, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π² LTW, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ аспСктами AspectJ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΡ… Π»ΠΈΠ±ΠΎ Π½Π° самом языкС AspectJ, Π»ΠΈΠ±ΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ свои аспСкты Π² стилС @AspectJ. Π’ΠΎΠ³Π΄Π° ваши аспСкты Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ допустимыми аспСктами ΠΈ AspectJ, ΠΈ Spring AOP. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, скомпилированныС классы аспСктов Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ доступны Π² ΠΏΡƒΡ‚ΠΈ классов.

'META-INF/aop.xml'

Π˜Π½Ρ„Ρ€Π°ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° AspectJ LTW конфигурируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² META-INF/aop.xml, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ находятся Π² ΠΏΡƒΡ‚ΠΈ классов Java (Π»ΠΈΠ±ΠΎ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, Π»ΠΈΠ±ΠΎ, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎ, Π² jar-Ρ„Π°ΠΉΠ»Π°Ρ…).

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΈ содСрТаниС этого Ρ„Π°ΠΉΠ»Π° ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описаны Π² части справочной Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ AspectJ, посвящСнной LTW. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ„Π°ΠΉΠ» aop.xml Π½Π° 100% написан Π½Π° AspectJ, ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ здСсь.

НСобходимыС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ (JARS)

Для использования ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW ΠΈΠ· AspectJ Π² Spring Framework Π²Π°ΠΌ понадобятся, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ:

  • spring-aop.jar

  • aspectjweaver.jar

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π°Π³Π΅Π½Ρ‚ для Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ инструмСнтирования, прСдоставляСмый Spring, Π²Π°ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ потрСбуСтся:

  • spring-instrument.jar

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Spring

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW Π² Spring являСтся интСрфСйс LoadTimeWeaver (Π² ΠΏΠ°ΠΊΠ΅Ρ‚Π΅ org.springframework.instrument.classloading) ΠΈ многочислСнныС Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, поставляСмыС с дистрибутивом Spring. LoadTimeWeaver ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… java.lang.instrument.ClassFileTransformers Π² ClassLoader Π²ΠΎ врСмя выполнСния, Ρ‡Ρ‚ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π΄Π²Π΅Ρ€ΠΈ для всСвозмоТных интСрСсных Ρ€Π΅ΠΆΠΈΠΌΠΎΠ² примСнСния, ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… являСтся связываниС аспСктов Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.

Если Π²Ρ‹ Π½Π΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с ΠΈΠ΄Π΅Π΅ΠΉ прСобразования Ρ„Π°ΠΉΠ»ΠΎΠ² классов Π²ΠΎ врСмя выполнСния, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ javadoc ΠΏΠΎ API-интСрфСйсу для ΠΏΠ°ΠΊΠ΅Ρ‚Π° java.lang.instrument, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ. Π₯отя эта докумСнтация Π½Π΅ являСтся ΠΈΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅ΠΉ, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, Π²Ρ‹ смоТСтС Π²ΠΈΠ΄Π΅Ρ‚ΡŒ основныС интСрфСйсы ΠΈ классы (для справки ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ этого Ρ€Π°Π·Π΄Π΅Π»Π°).

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ LoadTimeWeaver для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ApplicationContext ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΊ добавлСнию ΠΎΠ΄Π½ΠΎΠΉ строки. (ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ ΠΏΠΎΡ‡Ρ‚ΠΈ навСрняка Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ApplicationContext Π² качСствС ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° Spring - ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ BeanFactory нСдостаточно, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ BeanFactoryPostProcessors).

Π§Ρ‚ΠΎΠ±Ρ‹ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° LTW Π² Spring Framework, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ LoadTimeWeaver, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ дСлаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @EnableLoadTimeWeaving, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅:

Java
@Configuration
@EnableLoadTimeWeaving
public class AppConfig {
}
Kotlin
@Configuration
@EnableLoadTimeWeaving
class AppConfig {
}

Как Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Ссли Π²Ρ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π½Π° основС XML, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ элСмСнт <context:load-time-weaver/>. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ элСмСнт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π² пространствС ΠΈΠΌΠ΅Π½ context. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ <context:load-time-weaver/>:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:load-time-weaver/>
</beans>

ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π°Ρ конфигурация автоматичСски опрСдСляСт ΠΈ рСгистрируСт для вас ряд инфраструктурных Π±ΠΈΠ½ΠΎΠ², спСцифичных для LTW, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ LoadTimeWeaver ΠΈ AspectJWeavingEnabler. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ LoadTimeWeaver – это класс DefaultContextLoadTimeWeaver, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пытаСтся Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΉ LoadTimeWeaver. Π’ΠΎΡ‡Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ LoadTimeWeaver, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ "ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ автоматичСски", зависит ΠΎΡ‚ вашСй срСды выполнСния. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ LoadTimeWeaver:

Π’Π°Π±Π»ΠΈΡ†Π° 13. DefaultContextLoadTimeWeaver LoadTimeWeaver
Π‘Ρ€Π΅Π΄Π° выполнСния РСализация LoadTimeWeaver

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² Apache Tomcat

TomcatLoadTimeWeaver

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² GlassFish (ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ΠΌ EAR)

GlassFishLoadTimeWeaver

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² JBoss AS ΠΎΡ‚ Red Hat ΠΈΠ»ΠΈ WildFly

JBossLoadTimeWeaver

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² WebSphere ΠΎΡ‚ IBM

WebSphereLoadTimeWeaver

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² WebLogic ΠΎΡ‚ Oracle

WebLogicLoadTimeWeaver

JVM Π·Π°ΠΏΡƒΡ‰Π΅Π½Π° с InstrumentationSavingAgent(java -javaagent:path/to/spring-instrument.jar) ΠΈΠ· Spring

InstrumentationLoadTimeWeaver

Π’ΠΎΠ·Π²Ρ€Π°Ρ‚, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΉ, Ρ‡Ρ‚ΠΎ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ ClassLoader Π±ΡƒΠ΄ΡƒΡ‚ ΡΠΎΠ±Π»ΡŽΠ΄Π΅Π½Ρ‹ ΠΎΠ±Ρ‰ΠΈΠ΅ соглашСния (Π° ΠΈΠΌΠ΅Π½Π½ΠΎ addTransformer ΠΈ, ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ, ΠΌΠ΅Ρ‚ΠΎΠ΄ getThrowawayClassLoader).

ReflectiveLoadTimeWeaver

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ пСрСчислСны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ LoadTimeWeaver, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ автоматичСски ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ использовании DefaultContextLoadTimeWeaver. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ LoadTimeWeaver ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ.

Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ LoadTimeWeaver с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Java-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ интСрфСйс LoadTimeWeavingConfigurer ΠΈ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ getLoadTimeWeaver(). Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π°Π΄Π°Π½ ReflectiveLoadTimeWeaver:

Java
@Configuration
@EnableLoadTimeWeaving
public class AppConfig implements LoadTimeWeavingConfigurer {
    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new ReflectiveLoadTimeWeaver();
    }
}
Kotlin
@Configuration
@EnableLoadTimeWeaving
class AppConfig : LoadTimeWeavingConfigurer {
    override fun getLoadTimeWeaver(): LoadTimeWeaver {
        return ReflectiveLoadTimeWeaver()
    }
}

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π½Π° основС XML, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΠ΅ имя класса ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° weaver-class Π² элСмСнтС <context:load-time-weaver/>. ΠžΠΏΡΡ‚ΡŒ ΠΆΠ΅, Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π°Π΄Π°Π½ ReflectiveLoadTimeWeaver:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:load-time-weaver
            weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</beans>

LoadTimeWeaver, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΈ зарСгистрирован ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΈΠ· ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° Spring с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ общСизвСстного ΠΈΠΌΠ΅Π½ΠΈ loadTimeWeaver. ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ LoadTimeWeaver сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ для инфраструктуры LTW Π² Spring, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько ClassFileTransformers. ЀактичСский ClassFileTransformer, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСт LTW, – это класс ClassPreProcessorAgentAdapter (ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° org.aspectj.weaver.loadtime). Π‘ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² javadoc класса ClassPreProcessorAgentAdapter, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ спСцифика Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ происходит связываниС, Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π° Ρ€Π°ΠΌΠΊΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.

ΠžΡΡ‚Π°Π»ΠΎΡΡŒ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ послСдний Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ: Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ aspectjWeaving (ΠΈΠ»ΠΈ aspectj-weaving, Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ XML). Π­Ρ‚ΠΎΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚, Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½ Π»ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ LTW ΠΈΠ»ΠΈ Π½Π΅Ρ‚. Он ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Ρ‚Ρ€Π΅Ρ… Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΏΡ€ΠΈ этом Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ являСтся autodetect, Ссли Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ отсутствуСт. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ Ρ‚Ρ€ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… значСния:

Π’Π°Π±Π»ΠΈΡ†Π° 14. ЗначСния Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° связывания AspectJ
Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ XML ПояснСниС

ENABLED

Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ

БвязываниС AspectJ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Π° связываниС аспСктов происходит Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ нСобходимости.

DISABLED

ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ

БвязываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ. БвязываниС аспСктов Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π½Π΅ происходит.

AUTODETECT

автоматичСскоС ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅

Если инфраструктурС LTW Π² Spring удастся Π½Π°ΠΉΡ‚ΠΈ хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» META-INF/aop.xml, Ρ‚ΠΎ связываниС AspectJ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС связываниС Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ срСды

Π”Π°Π½Π½Ρ‹ΠΉ послСдний Ρ€Π°Π·Π΄Π΅Π» содСрТит всС Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΡ€ΠΈ использовании ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ LTW ΠΈΠ· Spring Π² Ρ‚Π°ΠΊΠΈΡ… срСдах, ΠΊΠ°ΠΊ сСрвСры ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π²Π΅Π±-ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹.

Tomcat, JBoss, WebSphere, WebLogic

Tomcat, JBoss/WildFly, IBM WebSphere Application Server ΠΈ Oracle WebLogic Server - всС ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΎΠ±Ρ‰ΠΈΠΉ ClassLoader для ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, способный ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ локальноС инструмСнтированиС. Π ΠΎΠ΄Π½ΠΎΠΉ LTW ΠΈΠ· Spring ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эти Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ClassLoader для обСспСчСния связывания ΠΈΠ· AspectJ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ связываниС Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. Π’ частности, Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ сцСнарий запуска JVM, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ -javaagent:path/to/spring-instrument.jar.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² случаС с JBoss ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ сканированиС сСрвСра ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π» классы Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ фактичСски запустится. Быстрым ΠΎΠ±Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ являСтся Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊ Π²Π°ΡˆΠ΅ΠΌΡƒ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρƒ Ρ„Π°ΠΉΠ»Π° с ΠΈΠΌΠ΅Π½Π΅ΠΌ WEB-INF/jboss-scanning.xml со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ содСрТимым:

<scanning xmlns="urn:jboss:scanning:1.0"/>

Π£Π½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ΅ использованиС Java

Если трСбуСтся провСсти инструмСнтированиС классов Π² срСдах, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌΠΈ рСализациями LoadTimeWeaver, ΠΎΠ±Ρ‰ΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ являСтся Π°Π³Π΅Π½Ρ‚ JVM. Для Ρ‚Π°ΠΊΠΈΡ… случаСв Π² Spring Π΅ΡΡ‚ΡŒ InstrumentationLoadTimeWeaver, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ наличия спСцифичного для Spring (Π½ΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ) Π°Π³Π΅Π½Ρ‚Π° JVM, spring-instrument.jar, автоматичСски опрСдСляСмого ΠΎΠ±Ρ‰ΠΈΠΌΠΈ настройками @EnableLoadTimeWeaving ΠΈ <context:load-time-weaver/>.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ, Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΌΠ°ΡˆΠΈΠ½Ρƒ с Π°Π³Π΅Π½Ρ‚ΠΎΠΌ ΠΈΠ· Spring, ΡƒΠΊΠ°Π·Π°Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ для JVM:

-javaagent:/path/to/spring-instrument.jar

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ для этого трСбуСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ скрипт запуска JVM, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠ΅ΡˆΠ°Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² срСдах сСрвСра ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ (Π² зависимости ΠΎΡ‚ вашСго сСрвСра ΠΈ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊ эксплуатации). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π² сцСнариях развСртывания ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹Π΅ прилоТСния Spring Boot, ΠΏΠΎ схСмС "ΠΎΠ΄Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΎΠ΄Π½Ρƒ JVM" Π²Π°ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ приходится ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ настройку JVM Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ Π² любом случаС.

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ рСсурсы

Π‘ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± AspectJ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° Π²Π΅Π±-сайтС AspectJ.

Eclipse AspectJ Π·Π° авторством Адриана КольС ΠΈ Π΄Ρ€. (Addison-Wesley, 2005) содСрТит ΠΈΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅Π΅ Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈ справочник ΠΏΠΎ языку AspectJ.

ΠΠ°ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ рСкомСндуСтся Π²Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ "AspectJ Π² дСйствии" Π·Π° авторством Рамниваса Π›Π°Π΄Π΄Π°Π΄Π° (Manning, 2009) ОсновноС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π² ΠΊΠ½ΠΈΠ³Π΅ ΡƒΠ΄Π΅Π»Π΅Π½ΠΎ AspectJ, Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΎΠ±Ρ‰ΠΈΠ΅ Ρ‚Π΅ΠΌΡ‹ АОП Ρ‚ΠΎΠΆΠ΅ исслСдованы (достаточно Π³Π»ΡƒΠ±ΠΎΠΊΠΎ).

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ (1)
  • популярныС
  • Π½ΠΎΠ²Ρ‹Π΅
  • старыС
Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ
30 сСнтября 2023, 20:36
YO!