https://sundaland.tistory.com/99
[ ▶ Programmatic Creation of @AspectJ Proxies ]
<aop:config> 또는 <aop:aspectj-autoproxy>를 사용하여 설정에서 aspect를 선언하는 것 외에도, 타겟 객체를 어드바이스하는 프록시를 프로그래밍 방식으로 생성할 수도 있다.
@AspectJ aspect를 사용하여 자동으로 프록시를 생성할 수 잇다.
org.springframework.aop.aspectj.annotation.AspectJProxyFactory 클래스를 사용하여 하나 의상의 @AspectJ aspect에 의해 어드바이스된 타겟 객체에 대한 프록시를 생성할 수 있다.
// 주어진 타겟 객체에 대한 프록시를 생성할 수 있는 팩토리를 생성합니다.
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);
// aspect를 추가합니다. 클래스는 @AspectJ aspect여야 합니다.
// 필요한 경우 다른 aspect로 여러 번 이 메서드를 호출할 수 있습니다.
factory.addAspect(SecurityManager.class);
// 기존 aspect 인스턴스를 추가할 수도 있습니다. 제공된 객체의 타입은
// @AspectJ aspect여야 합니다.
factory.addAspect(usageTracker);
// 이제 프록시 객체를 가져옵니다...
MyInterfaceType proxy = factory.getProxy();
[ ▷ Using AspectJ with Spring Applications ]
1. 스프링에서 AspectJ 소개
- 스프링 AOP vs AspectJ: 스프링 AOP는 더 넓은 AspectJ 프레임워크의 하위 집합이다. 스프링 AOP는 기업 애플리케이션의 일반적인 문제를 해결하도록 설계되었지만, 메서드 수준의 인터셉터에만 한정되며 필드 수준이나 생성자 수준의 인터셉션을 지원하지 않는다. 반면 AspectJ는 이를 지원한다.
- AspectJ를 사용하는 이유: AspectJ는 더 강력하고 유연한 AOP 접근 방식을 제공한다. 특히 스프링 AOP가 제공하는 기능을 넘어서는 추가 기능이 필요한 애플리케이션의 경우, AspectJ와 스프링을 통합하는 것이 유용할 수 있다.
2. Spring-Aspects 라이브러리
- AspectJ와 스프링의 통합: 스프링은 AspectJ에 대한 소규모 라이브러리를 포함하고 있으며, 이 라이브리는 spring-aspects.jar 파일에서 찾을 수 있다. 이 라이브러리는 사전에 구축된 AspectJ들을 제공하여 스프링 애플리케이션에서 사용할 수 있다.
- Spring-Asepcts 사용: 이 Aspect들을 사용하려면 애플리케이션의 클래스 경로에 spring-aspects.jar 파일을 포함시켜야 한다. 이를 통해 스프링에서 제공하는 사전 저의된 Aspect들을 활용하고 애플리케이션의 기능과 통합할 수 있다.
3. AspectJ에서 스프링을 사용한 의존성 주입
- 스프링 IoC와 함께 AspectJ 사용: 스프링과 AspectJ 간의 주요 통합 기능 중 하나는 스프링의 IoC (Inversion of Control) 컨테이너는 사용하여 AspectJ Aspect들을 관리할 수 있다는 것이다. 이를 통해 Aspect들이 스프링 의존성 주입을 사용할 수 있다.
- AspectJ Aspect 설정: AspectJ Aspect를 설정할 때 스프링의 XML 또는 자바 기반 설정을 사용할 수 있다. 이 설정에서는 Aspect를 스프링 빈으로 정의하여 스프링 컨테이너에서 관리하는 의존성을 주입받을 수 있다.
4. AspectJ의 로드 타임 위빙 (LTW)
- LTW 소개: 로드 타임 위빙은 클래스가 클래스 로더에 의래 로드될 때 Aspect가 클래스에 삽입되는 과정이다. 이는 빌드 타임이나 포스트 컴파일 위방과 달리, 코드가 로드될 때 Aspect가 삽입된다.
- 스프링에서의 LTW: 스프링은 AspectJ와 함께 로드 타임 위빙을 지원하여 원본 소스 코드를 수정하지 않고도 Aspect를 추가하거나 런타임에 조건부로 Aspect를 적용해야 할 때 특히 유용하다.
- LTW 설정: 스프링에서 로드 타임 위빙을 활성화하려면 @EnableLoadTimeWeaving 어노테이션 또는 해당 XML 설정을 포함하도록 스프링 애플리케이션 컨텍스트를 설정해야 한다. 또한 전통적인 자바 애플리케이션을 사용하는 경우 AspectJ 에이전트를 JVM 옵션에 지정해야 한다.
5. 스프링과 AspectJ 사용
- 컴파일 타임 위빙: AspectJ는 스프링 애플리케이션의 빌드 프로세스에 통합되어 컴파일 타임에 Aspect를 삽입할 수 있다. 이를 위해 표준 자바 컴파일러 대신 AspectJ 컴파일러를 사용해야 한다.
- 런타임 (로드 타임) 위빙: 또는 스프링의 로드 타임 위빙 기능을 사용하여 런타임에 Aspect를 적용할 수도 있다. 이는 유연성을 제공하지만 적절한 클래스 로더를 구성해야 한다.
AspectJ와 스프링을 통합하면 스프링 AOP의 한계를 넘어선 더 강력하고 유연한 AOP 프레임 워크를 사용할 수 있다. 프로젝트에 spring-aspects.jar을 포함시킴으로써 사전 정의된 Aspect를 사용할 수 있으며, 스프링 IoC를 통해 AspectJ Aspect를 스프링 빈으로 관리할 수 있다. 필드나 생성자 인터셉션과 같은 더 고급 AOP 기능이 필요하거나 런타임에 동적으로 Aspect를 적용해야 하는 애플리케이션의 경우, 로드 타임 위빙이 효과적인 접근 방식일 될 수 잇다. AspectJ와 스프링을 설정하여 애플리케이션의 모듈화 및 횡단 관심사 기능을 강화할 수 있다.
[ ▶ Using AspectJ to Dependency Inject Domain Objects with Spring ]
스프링 프레임워크에서 AspectJ를 사용하여 도메인 객체에 의존성을 주입할 수 있다. 이 기법은 스프링 컨테이너의 제어 밖에서 생성된 객체들에 의존성을 주입할 수 있도록 해준다. 특히 ORM 도구를 통해 생성되거나 new 연산자로 생상된 도메인 객체에 유용하다.
[ ▷ 스프링의 의존성 주입과 도메인 객체 ]
스프링 컨테이너는 애플리케이션 컨텍스트에 정의된 빈을 인스턴스화하고 설정하는 역할을 한다. 일반적으로 스프링 컨테이너가 관리하는 객체들은 애플리케이션 컨텍스트에서 정의된 빈으로부터 생성된다. 그러나 도메인 객체들은 종종 프로그래밍 방식으로 new 연산자를 사용하여 생성되거나 ORM 도구를 통해 데이터베이스 쿼리 결과로 생성되기 떄문에, 스프링 컨테이너의 제어 밖에서 생성될 때가 많다.
이러한 경우, 스프링은 @Configurable 어노테이션과 AspectJ를 활용하여 이러한 객체에 의존성을 주입할 수 있다.
[ ▷ @Configurable 어노테이션 ]
@Configurable 어노테이션은 클래스가 스프링을 통해 설정될 수 있음을 나타낸다. 이 어노테이션을 사용하면, 해당 클래스의 새로운 인스턴스가 생성될 때 스프링 컨테이너에서 해당 클래스의 빈 정의를 기반으로 의존성이 주입된다.
[ ▷ 기본적인 사용법 ]
가장 간단한 형태의 @Configurable 어노테이션은 마커 (Marker) 어노테이션으로 사용할 수 있다.
package com.xyz.domain;
import org.springframework.beans.factory.annotation.Configurable;
// 스프링 IoC에 의해 관리되는 빈이 아니다.
@Configurable
public class Account {
// ...
// MyService는 스프링 IoC에 의해 관리되는 빈이다.
MyService myService;
}
이 경우, 스프링은 com.xyz.domain.Account라는 이름의 빈 정의를 찾아 새롭게 생성된 Account 객체에 이를 적용한다.
@Configurable(autowire=Autowire.BY_TYPE)
// 혹은
@Configurable(autowire=Autowire.BY_NAME)
이 외에도, @Autowired 또는 @Inject 어노테이션을 필드나 메서드 레벨에 사용하여 명시적으로 의존성을 주입할 수 있다.
[ ▷ 명시적인 빈 이름 설정 ]
빈 정의의 이름을 명시적으로 설정하고 싶다면, @Configurable 어노테이션에 이름을 지정할 수 있다.
package com.xyz.domain;
import org.springframework.beans.factory.annotation.Configurable;
@Configurable("account")
public class Account {
// ...
}
이 경우 스프링은 account라는 이름의 빈 정의를 찾아 사용한다.
[ ▷ 자동 주입 (Autowiring) ]
빈 정의를 따로 만들지 않고 자동으로 의존성을 주입하려면, @Configurable 어노테이션의 autowired 속성을 사용하여 자동 주입을 설정할 수 있다.
@Configurable(autowire=Autowire.BY_TYPE)
// 또는
@Configurable(autowire=Autowire.BY_NAME)
이 외에도 @Autowired 또는 @inject 어노테이션을 필드나 메서드 레벨에 사용하여 명시적으로 의존성을 주입할 수 있다.
[ ▷ AspectJ와 @Configurable ]
@Configurable 어노테이션만으로는 아무런 동작도 하지 않는다. 이 어노테이션이 실제로 동작하려면 AspectJ의 AnnotationBeanConfigurerAspect가 필요하다. 이 애스펙트는 @Configurable이 적용된 클래스의 인스턴스가 생성된 후, 해당 객체를 스프링을 통해 구성하도록 한다.
[ ▷ 사후 초기화 (After Initialization) ]
기본적으로 @Configurable을 사용하면, 객체가 생성된 후에 의존성이 주입된다. 즉, 객체 생성자의 본문에서 의존성을 사용할 수 없다. 만약 의존성을 생성자에 사용하고 싶다면, @Configurable(preConstruction=true)를 사용하여 생성자 실행 전에 의존성을 주입할 수 있도록 설정할 수 있다.
@Configurable(preConstruction = true)
이렇게 하면 생성자 본문 실행 전에 의존성이 주입된다.
[ ▷ AspectJ Weaving ]
@Configurable이 적용된 클래스는 AspectJ를 통해 위빙 되어야 한다. 이를 위해, 빌드 타임에 Ant 또는 Maven 태스트를 사용하거나, 로드 타임 위빙을 사용할 수 있다.
AnnotationBeanConfigurerAspect 자체도 스프링에서 설정되어야 하며, 이를 위해 자바 기반 설정에서는 @EnableSpringConfigured를 사용하여 설정할 수 있다.
@Configuration
@EnableSpringConfigured
public class AppConfig {
}
만약 XML 기반 설정을 선호하는 경우에는, 스프링의 context:spring-configured 요소를 사용하여 설정할 수 있다.
<context:spring-configured/>
[ ▷ 주의 사항 ]
@Configurable 처리를 활성화할 때는 해당 클래스가 일반적인 스프링 빈으로 등록되지 않도록 주의햐 한다. 그렇지 않으면 해당 클래스가 두 번 초기화되는 문제가 발생할 수 있다.
AspectJ와 스프링은 @Configurable 어노테이션을 활용하며, 스프링 컨테이너의 제어 밖에서 생성된 객체에도 의존성을 주입할 수 있다. 이 방법은 특히 도메인 객체와 같은 스프링의 관리 대상이 아닌 객체에 대해 유용하게 사용될 수 있다. 그러나 이 기능을 사용할 때는 의존성 주입의 시점과 클래스 초기화 과정에서 발생할 수 있는 문제를 충분히 이해하고 사용하는 것이 중요하다.
[ ▷ Unit Testing @Configurable Objects ]
@Configurable 지원의 목표 중 하나는 도메인 객체의 독립적인 단위 테스트를 어렵지 않게 수행할 수 있도록 하는 것이다. @Configurable 타입이 AspectJ에 의해 위빙되지 않은 경우, 어노테이션은 단위 테스트 중에는 아무런 영향을 미치지 않는다. 테스트 중에는 모의 (Mock)나 스텁 (Stub) 속서을 설정한 후 정상적으로 진행할 수 있다. 그러나 @Configurable 타입이 AspectJ에 의해 위빙된 경우, 단위 테스트를 컨테이너 외부에서 수행할 때마다 경고 메시지가 나타나며, 이는 객체가 스프링에 의해 구성되지 않았음을 나타낸다.
[ ▷ Working with Multiple Application Contexts ]
@Configurable 지원을 구현하는 AnnotationBeanConfigurerAspect는 AspectJ 싱글톤 에스팩트이다. 싱글톤 애스펙트의 범위는 정적 멤버 범위와 동일하다. 해당 타입을 정의하는 클래스 로더당 하나의 애스펙트 인스턴스가 존재한다. 이는 동일한 클래스 로더 계층 구조 내에서 여러 애플리케이션 컨텍스트를 정의하는 경우, @EnableSrpingConfigured 빈을 어디에 정의하고 spring-aspects.jar을 클래스패스에 어디에 배치할지 고려해야 함을 의미한다.
일반적인 스프링 웹 애플리케이션 구성에서는 공유 부모 애플리케이션 컨테스트가 공통 비즈니스 서비스와 이를 지원하는 는 모든 것을 정의하고, 각 서블릿에 대해 자식 애플리케이션 켄턱스트가 존재하는 경우가 많다. 이러한 컨텍스트는 동일한 클래스 로더 계층 내에서 공존하므로, AnnotationBeanConfigurerAspect는 그 중 하나에만 참조를 가질 수 있다. 이 경우, 공유 (부모) 애플리케이션 컨텍스트에 @EnableSpringConfigured 빈을 정의하는 것이 좋다. 이는 도메인 객체에 주입할 가능성이 높은 서비스들을 정의하는 것이다. 결과적으로, @Configurable 메커니즘을 사용하여 자식 (서블릿 전용) 컨텍스트에 정의된 빈에 대한 참조로 도메인 객체를 구성할 수 없다.
같은 컨테이너 내에서 여러 웹 애플리케이션을 배포할 때는, 각 웹 애플리케이션이 spring-aspects.jar을 자체 클래스 로더를 통해 로드하도록 해야 한다. (예를 들어 WEB-INF/lib에 spring-aspects.jar를 배치). spring-aspects.jar이 컨테이너 전체 클래스패스에만 추가된 경우, 모든 웹 애플리케이션이 동일한 에스펙트 인스턴스를 공유하게 되며, 이는 원하지 않는 상황이 된다.
[ ▷ Other Spring aspects for AspectJ ]
@Configurable 에스펙트 외에도 spring-aspects.jar에는 @Transactional 어노테이션이 적용된 타입과 메서드에 대해 스프링의 트랜잭션 관리를 사용할 수 있는 AspectJ 에스펙트가 포함되어 있다. 이 에스펙트는 주로 스프링 컨테이너 외부에서 스프링 프레임워크의 트랜잭션 지원을 사용하려는 사용자를 위한 것이다.
@Transactional 어노테이션을 해석하는 에스펙트는 AnnotationTransactionAspect이다. 이 에스펙트를 사용할 때는 구현 클래스 (또는 해당 클래스 내의 메서드 또는 둘다)에 어노테이션을 달아야 하며, 클래스가 구현하는 인터페이스에는 어노테이션을 달지 않아야 한다. 이는 AspectJ가 자바의 규칙을 따르기 때문인데, 인터페이스에 있는 어노테이션은 상속되지 않는다.
클래스에 @Transactional 어노테이션을 적용하면, 그 클래스 내의 모든 public 메서드 실행에 대해 기본 트랜잭션 규칙이 적용된다.
클래스 내의 메서드에 @Transactional 어노테이션을 적용하면, 해당 메서드에 대해 클래스에 지정된 기본 트랜잭션 규칙을 재정의한다. (클래스 어노테이션이 있는 경우), 접근 제한자에 관계없이 모든 메서드에 어노테이션을 달 수 있으며, private 메서드에 트랜잭션 구역을 적용하려면 직접 어노테이션을 달아야 한다.
스프링 프레임 워크는 4.2부터, spring-aspects는 표준 jakarta.transaction.Transactional 어노테이션에 대해 동일한 기능을 제공하는 유사한 에스펙트를 제공한다.
AspectJ 프로그래머 중 스프링의 구성과 트랜잭션 관리 지원을 사용하고 싶지만 어노테이션을 사용하지 않거나 사용할 수 없는 경우, spring-aspects.jar에는 자체 포인트컷 정의를 제공할 수 있는 추상 에스펙트가 포함되어 있다.
예를 들어 아래의 코드는 도메인 모델에 저으이된 객체의 모든 인스턴스를 클래스 전체 경로 이름과 일치하는 프로토타입 빈 정의를 사용하여 구성하는 에스펙트를 작성하는 방법을 보여준다.
public aspect DomainObjectConfiguration extends AbstractBeanConfigurerAspect {
public DomainObjectConfiguration() {
setBeanWiringInfoResolver(new ClassNameBeanWiringInfoResolver());
}
// the creation of a new bean (any object in the domain model)
protected pointcut beanCreation(Object beanInstance) :
initialization(new(..)) &&
CommonPointcuts.inDomainModel() &&
this(beanInstance);
}
[ ▷ Configuring AspectJ Aspects by Using Spring IoC ]
스프링 애플리케이션에서 AspectJ 에스펙트를 사용하는 경우, 이러한 에스펙트를 스프링으로 구성하는 것이 자연스럽다. AspectJ 런타임 자체가 에스펙트 생성을 담당하며, AspectJ 생성 모델에 따라 스프링을 통해 에스펙트를 구성하는 방법이 달라진다.
대부분의 AspectJ 에스펙트는 싱글톤 에스펙트이다. 이러한 에스펙트를 구성하는 것은 쉽다. 일반적인 빈 정의를 생성하고 factory-method="aspectOf" 속성을 포함하면 된다. 이렇게 하면 스프링이 인스턴스를 생성하는 대신 AspectJ에 요청하여 에스펙트 인스턴스를 가져온다.
<bean id="profiler" class="com.xyz.profiler.Profiler"
factory-method="aspectOf">
<property name="profilingStrategy" ref="jamonProfilingStrategy"/>
</bean>
싱글톤이 아닌 에스펙트는 구성하기 어렵지만, @Configurable 지원을 사용하여 AspectJ 런타임에서 생성된 에스펙트 인스턴스를 구성할 수 있다.
일부 @AspectJ 에스펙트를 AspectJ로 위빙하고 (예를 들어 도메인 모델 타입에 대한 로드 타임 위빙 사용), 다른 @AspectJ 에스펙트를 스프링 AOP와 함께 사용하려는 경우, 스프링 AOP @AspectJ 자동 프록시 지원이 구성에서 정의된 @AspectJ 에스펙트 중 어떤 부분을 자동 프록시 구성에 사용할지를 지정해야 한다.
▼ 스프링 AOP 프록시를 생성하는 코드
<aop:aspectj-autoproxy>
<aop:include name="thisBean"/>
<aop:include name="thatBean"/>
</aop:aspectj-autoproxy>
[ ▷ Spring Framework에서 AspectJ를 사용한 로드 타임 위빙 ]
로드 타임 위빙 (LTW)은 AspectJ 에스펙트를 애플리케이션의 클래스 파일에 위빙하는 과정을 의미한다. 이 섹션에서는 스프링 프레임워크를 사용하는 LTW 구성 및 사용법에 중점을 둔다.
스프링 프레임워크의 LTW 지원은 더 세밀한 위빙 제어를 가능하게 한다. 기본 AspectJ LTW는 자바 에이전트를 사용하여 JVM 시작 시 전역 설정으로 작동한다. 그러나 스프링은 LTW를 클래스 로더 별로 활성화할 수 있는 기능을 제공하여, 다중 애플리케이션 환경에서 더 유용하게 사용할 수 있다.
스프링의 LTW 지원은 애플리케이션 서버의 시작 스크립트를 수정하지 않고도 로드 타임 위빙을 활성화할 수 있다. 애플리케이션 컨텍스트를 구성하여 로드 타임 위빙을 활성화하면 된다.
[ ▷ 예제: Spring을 사용한 AspectJ LTW ]
아래의 예제는 성능 문제를 진단하기 위해 간단한 프로파일링 에스펙틑 활성화해 성능 메트릭을 수집하는 코드이다.
간단한 시간 기반 프로파일러를 사용하는 ProfilingAspect 클래스는 아래와 같다.
package com.xyz;
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;
@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 * com.xyz..*.*(..))")
public void methodsToBeProfiled(){}
}
이제 AspectJ 위버에서 ProfilingAspect를 클래스에 위빙하도록 지시하는 META-INF/aop.xml 파일을 생성한다.
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- 애플리케이션의 특정 패키지와 하위 패키지의 클래스에만 위빙 -->
<include within="com.xyz..*"/>
</weaver>
<aspects>
<!-- 이 에스펙트만 위빙 -->
<aspect name="com.xyz.ProfilingAspect"/>
</aspects>
</aspectj>
Spring-specific 부분의 설정의 다음과 같다. 로드 타임 위버를 구성하는 부분이다.
<?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="com.xyz.StubEntitlementCalculationService"/>
<!-- 로드 타임 위빙 활성화 -->
<context:load-time-weaver/>
</beans>
이제 Main 클래스에서 LTW 실행한다.
package com.xyz;
// imports
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
EntitlementCalculationService service =
ctx.getBean(EntitlementCalculationService.class);
// 프로파일링 에스펙트가 이 메서드 실행에 '위빙'됩니다.
service.calculateEntitlement();
}
}
마지막으로 아래 명령어를 사용하여 Main 클래스를 실행한다.
java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main
이 명령어는 스프링 프레임워크에서 제공하는 InstrumentationSavingAgent 에이전트를 활성화한다.
▼ 실행 결과
Calculating entitlement
StopWatch 'ProfilingAspect': running time (millis) = 1234
------ ----- ----------------------------
ms % Task name
------ ----- ----------------------------
01234 100% calculateEntitlement
이 예제는 간단하지만, LTW의 기본 사항은 모두 포함되어 있으며, 각 구성 요소의 설명이 포함되어 있다.
[ ▷ Spring Framework에서의 AspectJ LTW 설정 ]
AspectJ LTW를 사용하려면 최소한 아래의 라이브러리가 필요하다.
- spring-aop.jar
- aspectjweaver.jar
또한 LTW 지원을 위해 스프링의 LoadTimeWeaver 인터페이스를 사용해야 한다. 이는 @ EnableLoadTimeWeaving 어노테이션을 사용하여 활성화할 수 있다.
@Configuration
@EnableLoadTimeWeaving
public class AppConfig {
}
XML 기반을 구성을 사용하는 경우, <context:load-time-weaver/> 요소를 사용할 수 있다.
<context:load-time-weaver/>
기본적으로 스프링 LTW 인프라는 클래스 로더에서 ClassFileTransformer를 추가할 수 있도록 한다. 위빙 자체는 ClassPreProcessorAgentAdapter 클래스 의해 수행된다.
[ ▷ Environment-specific Configuration ]
스프링 LTW 지원을 Tomcat, JBoss, WildFly 등 다양한 환경에서 사용할 수 있으며, 각 환경에 맞게 설정이 가능하다. Tomcat과 JBoss/WildFly는 로컬 인스트루멘테이션을 지원하는 일반적인 애플리케이션 클래스 로더를 제공한다. 따라서 스프링의 네이티브 LTW는 이 클래스 로더 구현을 활용하여 AspectJ 위빙을 제공한다. Tomcat이나 JBoss/WildFly와 같은 서버에서는 JVM 시작 스크립트를 수정하지 않고 LTW를 활성화할 수 잇다.
기타 환경에서는 스프링이 제공하는 spring-instrument.jar JVM 에이전트를 사용하여 LTW를 활성화할 수 있다. 이를 위해 다음과 같은 JVM 옵션을 사용하여 가상 머신을 시작해야 한다.
-javaagent:/path/to/spring-instrument.jar
이 설정은 독립 실행형 스프링 부트 애플리케이션과 같은 1개의 애플리케이션만 있는 JVM 배포 환경에서 유용하다.
'스프링 AOP' 카테고리의 다른 글
Spring instrument library (0) | 2024.09.04 |
---|---|
Instrumentation API vs AspectJ (0) | 2024.09.04 |
Java Agent (1) | 2024.09.04 |
Java Instrument API vs ASM(Abstract Syntax Manipulation) (0) | 2024.09.03 |
Java Instrumentation API (0) | 2024.09.03 |