# jfinal-aop **Repository Path**: ppnt/jfinal-aop ## Basic Information - **Project Name**: jfinal-aop - **Description**: high-performance aop framework - **Primary Language**: Java - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-10-01 - **Last Updated**: 2026-03-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # jfinal-aop jfinal-aop 是一个基于 JVM 的高性能 AOP 框架,源自 JFinal AOP 模块,并在此基础上进行了独立演进。 框架采用 **动态生成 Java 源码并编译代理类** 的方式实现方法拦截,从而避免反射调用带来的性能损耗。 在运行时,jfinal-aop 会为存在拦截器的方法生成代理类,使最终的方法调用接近普通 Java 方法调用的性能。 当前版本 **不支持 AOT(Ahead-of-Time)编译模式**。 --- ## Maven 依赖 该包已发布到 Maven Central: https://central.sonatype.com/artifact/com.litongjava/jfinal-aop ```xml com.litongjava jfinal-aop 1.3.8 ```` --- # 基本使用 ## 创建类实例并调用 jfinal-aop 推荐通过 `Aop.get()` 创建对象,而不是直接使用 `new`。 这样框架才能为对象生成代理并启用拦截器。 ```java package com.litongjava.jfinal.aop; import org.junit.Test; public class AopTest { @Test public void test() { TestServices testServices = Aop.get(TestServices.class); testServices.print(); } } ``` --- # 切面使用示例 ## 1 Cat 类 定义一个普通类,并在方法上使用 `@AopBefore` 指定拦截器。 ```java package com.issues01; import com.litongjava.jfinal.aop.AopBefore; public class Cat { @AopBefore(Aspect1.class) public String eat() { return "eat chat"; } } ``` --- ## 2 拦截器实现 拦截器实现 `AopInterceptor` 接口。 在 `intercept` 方法中可以: * 获取方法信息 * 获取参数 * 控制方法执行 * 修改返回值 ```java package com.issues01; import com.litongjava.jfinal.aop.AopInterceptor; import com.litongjava.jfinal.aop.AopInvocation; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Method; import java.util.Arrays; @Slf4j public class Aspect1 implements AopInterceptor { @Override public void intercept(AopInvocation invocation) { System.out.println("Before Aspect1 invoking"); Method method = invocation.getMethod(); String methodName = invocation.getMethodName(); Object[] args = invocation.getArgs(); Object target = invocation.getTarget(); log.info("method:{}", method); log.info("methodName:{}", methodName); log.info("args:{}", Arrays.toString(args)); log.info("target:{}", target); Object invoke = invocation.invoke(); invocation.setReturnValue("set new value"); log.info("invoke:{}", invoke); System.out.println("After Aspect1 invoking"); } } ``` --- ## 3 启动测试 ```java package com.issues01; import com.litongjava.jfinal.aop.Aop; public class CatMainTest { public static void main(String[] args) { new CatMainTest().index(); } public void index() { String javaVersion = System.getProperty("java.version"); System.out.println("java-version:" + javaVersion); Cat cat = Aop.get(Cat.class); String eat = cat.eat(); System.out.println("result:" + eat); } } ``` --- ## 运行输出 ``` Generate proxy class "com.issues01.Cat$$EnhancerByJFinal": package com.issues01; import com.litongjava.jfinal.aop.AopInvocation; public class Cat$$EnhancerByJFinal extends Cat { public String eat() { AopInvocation inv = new AopInvocation(this, 1L, args -> { return Cat$$EnhancerByJFinal.super.eat(); } ); inv.invoke(); return inv.getReturnValue(); } } ``` 拦截器输出: ``` Before Aspect1 invoking method:public java.lang.String com.issues01.Cat.eat() methodName:eat args:[] target:com.issues01.Cat$$EnhancerByJFinal invoke:eat chat After Aspect1 invoking result:set new value ``` --- # 扫描类并初始化 jfinal-aop 支持组件扫描与依赖注入。 下面示例展示如何扫描组件并自动注入依赖。 --- ## DemoService 接口 ```java package com.issues02; public interface DemoService { String Hello(); } ``` --- ## DemoServiceImpl 实现类 ```java package com.issues02; import com.litongjava.jfinal.aop.annotation.Service; @Service public class DemoServiceImpl implements DemoService { public String Hello() { return "Hello"; } } ``` --- ## DemoController ```java package com.issues02; import com.litongjava.jfinal.aop.Autowired; import com.litongjava.jfinal.aop.annotation.Controller; @Controller public class DemoController { @Autowired private DemoService demoService; public String hello() { return demoService.Hello(); } } ``` --- ## DemoApp 启动类 ```java package com.issues02; import com.litongjava.jfinal.aop.Aop; import java.util.List; public class DemoApp { public static void main(String[] args) throws Exception { List> scannedClasses = Aop.scan(DemoApp.class); Aop.initAnnotation(scannedClasses); DemoController demoController = Aop.get(DemoController.class); String hello = demoController.hello(); System.out.println(hello); Aop.close(); } } ``` --- 运行输出: ``` Hello ``` --- # 使用 registerInterceptor 绑定注解与拦截器 jfinal-aop 支持将 **自定义注解与拦截器自动绑定**。 这样业务代码无需直接依赖拦截器类。 例如实现一个事务注解: ``` @ATransactional ``` 而不是: ``` @AopBefore(TransactionInterceptor.class) ``` --- ## 定义注解 ```java package demo.jooq.tx; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ATransactional { } ``` --- ## 定义事务拦截器 ```java package demo.jooq.tx; import com.litongjava.jfinal.aop.Aop; import com.litongjava.jfinal.aop.AopInterceptor; import com.litongjava.jfinal.aop.AopInvocation; public class TransactionInterceptor implements AopInterceptor { @Override public void intercept(AopInvocation inv) { TransactionManager txManager = Aop.get(TransactionManager.class); txManager.tx(() -> { inv.invoke(); }); } } ``` --- ## 注册注解拦截器 在系统启动时进行注册: ```java package demo.jooq.config; import com.litongjava.context.BootConfiguration; import com.litongjava.jfinal.aop.AopInterceptorManager; import demo.jooq.tx.ATransactional; import demo.jooq.tx.TransactionInterceptor; public class JooqBootConfig implements BootConfiguration { @Override public void config() { AopInterceptorManager.me() .registerInterceptor(ATransactional.class, TransactionInterceptor.class); } } ``` --- ## 使用事务注解 ```java package demo.jooq.service; import demo.jooq.tx.ATransactional; public class SystemAdminService { @ATransactional public void changePassword2(String loginName, String newPassword) { systemAdminDao.updatePassword(loginName, newPassword); } } ``` 此时框架会自动为该方法应用 `TransactionInterceptor`。 --- # 设计原理 jfinal-aop 的核心思想是: 1. 扫描类方法 2. 判断方法是否存在拦截器 3. 动态生成代理类源码 4. 编译并加载代理类 5. 代理方法通过 `AopInvocation` 执行拦截器链 生成的代理方法类似: ```java public String test() { AopInvocation inv = new AopInvocation(this, methodKey, args -> { return super.test(); } ); inv.invoke(); return inv.getReturnValue(); } ``` 由于代理代码是普通 Java 方法调用,因此避免了反射调用带来的性能损耗。 --- # 项目特点 * 基于 JVM 的高性能 AOP * 动态生成代理类源码 * 避免反射调用 * 支持拦截器链 * 支持组件扫描 * 支持依赖注入 * 支持注解拦截器注册 --- # 注意事项 1. 请使用 `Aop.get()` 创建对象,否则不会生成代理。 2. 拦截器需要实现 `AopInterceptor` 接口。 3. `registerInterceptor` 必须在应用启动阶段执行。 4. 当前版本 **不支持 AOT 编译模式**。 --- # License Apache License 2.0