Aspect的AOP实现
Spring的Aop实现的常见形式是通过两种动态代理的形式,除此之外还有另一种实现,它可以通过改写目标类的class文件来实现AOP增强。
1.引入Aspectj编译器的依赖
<!-- AspectJ Maven Plugin --><plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.14.0</version> <!-- 请使用最新版本 --><configuration><!-- 指定使用哪个版本的AspectJ工具链 --><aspectjVersion>1.9.19</aspectjVersion><!-- 指定Java版本,与你的项目一致 --><source>11</source><target>11</target><!-- 启用Xlint警告,帮助调试切面 --><Xlint>warning</Xlint><!-- 这个配置很重要,确保插件的行为符合预期 --><complianceLevel>11</complianceLevel><encoding>UTF-8</encoding></configuration><executions><execution><goals><!-- 目标:在编译主代码时进行织入 --><goal>compile</goal><!-- 目标:在编译测试代码时进行织入 --><goal>test-compile</goal></goals></execution></executions></plugin>
2.Aspect切面类
package com.example.springdemo.demos.a28.aop;import com.example.springdemo.demos.a27.a27Application;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:04*/
@Aspect
public class MyAspect {private static final Logger log = LoggerFactory.getLogger(MyAspect.class);@Before("execution(* com.example.springdemo.demos.a28.service.MyService.test())")public void before(){log.info("before()");}}
3.MyService
package com.example.springdemo.demos.a28.service;import com.example.springdemo.demos.a27.a27Application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:08*/
@Service
public class MyService {private static final Logger log = LoggerFactory.getLogger(MyService.class);public void test(){log.info("test");}
}
4.测试主类
package com.example.springdemo.demos.a28;import com.example.springdemo.demos.a27.a27Application;
import com.example.springdemo.demos.a28.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:08*/
@SpringBootApplication
public class a28Application {private static final Logger log = LoggerFactory.getLogger(a28Application.class);public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(a28Application.class, args);MyService service = context.getBean(MyService.class);log.info("service class:{}",service.getClass());service.test();context.close();}
}
5.结果
在Service的test方法前实现了before增强。查看Service的class文件可以知道,它是通过改写Service的class文件并进行了方法增强。
6.直接new对象的方式调用
由于这种AOP的实现形式是不依赖于Spring容器的,所以可以直接创建对象并调用方法也能使用AOP增强,它完全依赖于Aspectj编译器。
package com.example.springdemo.demos.a28;import com.example.springdemo.demos.a27.a27Application;
import com.example.springdemo.demos.a28.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:08*/
@SpringBootApplication
public class a28Application {private static final Logger log = LoggerFactory.getLogger(a28Application.class);public static void main(String[] args) {/*ConfigurableApplicationContext context = SpringApplication.run(a28Application.class, args);MyService service = context.getBean(MyService.class);log.info("service class:{}",service.getClass());service.test();context.close();*/new MyService().test();}
}