能否仅用Java配置AspectJ加载时织入(LTW)?无需XML且适配Spring
Absolutely! You can set up AspectJ LTW using only Java code alongside Spring—no XML configuration required at all. I’ve used this approach before, so let me walk you through the steps to get it working smoothly, with tips to avoid common pitfalls.
1. Add Required Dependencies
First, make sure your build (Maven/Gradle) includes these core dependencies:
spring-aspects: For Spring’s native AspectJ integrationaspectjweaver: The core LTW agent that handles class weaving at load timespring-context: Basic Spring context support
2. Enable LTW via Java Config
Create a Spring configuration class and use the @EnableLoadTimeWeaving annotation to turn on LTW. This replaces the old XML <context:load-time-weaver> element:
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableLoadTimeWeaving; import org.springframework.context.annotation.EnableLoadTimeWeaving.AspectJWeaving; @Configuration // Force-enable AspectJ weaving; you can also use AUTODETECT to let Spring check the agent @EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED) public class LtwConfiguration { // Add any additional bean definitions here if needed }
If you need more control over the weaver implementation (e.g., for specific runtime environments), implement LoadTimeWeaverConfigurer:
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableLoadTimeWeaving; import org.springframework.context.annotation.LoadTimeWeaverConfigurer; import org.springframework.instrument.classloading.LoadTimeWeaver; import org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver; @Configuration @EnableLoadTimeWeaving public class CustomLtwConfig implements LoadTimeWeaverConfigurer { @Override public LoadTimeWeaver getLoadTimeWeaver() { // Use ReflectiveLoadTimeWeaver (works for most standard environments) return new ReflectiveLoadTimeWeaver(); } }
3. Define and Register Your Aspects
Write your AspectJ aspects as normal—no XML needed to register them. For example, a simple logging aspect:
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { // Pointcut targeting all methods in your application package @Before("execution(* com.yourapp..*(..))") public void logMethodStart() { System.out.println("Method execution is starting..."); } }
To make Spring pick up your aspect, either:
- Add
@Componentto the aspect class and enable component scanning in your config, or - Define it as a bean directly in your LTW configuration:
@Configuration @EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED) @ComponentScan(basePackages = "com.yourapp.aspects") public class LtwConfiguration { // Alternative: Register the aspect manually if not using component scan // @Bean // public LoggingAspect loggingAspect() { // return new LoggingAspect(); // } }
4. Configure the JVM Agent (Critical Step!)
Even with Java config, you still need to start your JVM with the AspectJ weaver agent—this is non-negotiable for LTW. Add this JVM argument when launching your app:
-javaagent:/path/to/aspectjweaver.jar
If you’re using Maven, you can automate this with the exec-maven-plugin so you don’t have to type it every time:
<!-- This is build config, not application XML—still no runtime XML needed! --> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <configuration> <executable>java</executable> <arguments> <argument>-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar</argument> <argument>-classpath</argument> <classpath/> <argument>com.yourapp.MainApplication</argument> </arguments> </configuration> </plugin> </plugins> </build>
5. Verify and Avoid Common Issues
Launch your Spring app, and your aspects should weave into target classes at load time without any XML hiccups. To prevent exceptions:
- Match versions: Ensure
aspectjweaverandspring-aspectsuse the same AspectJ version (e.g., 1.9.20) to avoid compatibility conflicts. - Server environments: If deploying to an app server (like Tomcat), configure the agent at the server level instead of per-app.
- Check pointcuts: Most "aspect not working" issues come from incorrect pointcuts, not LTW config—double-check your pointcut expressions.
内容的提问来源于stack exchange,提问作者user3285241

