关于proxy,运行在jre环境中

1、注解加在service中,会报错,提示没找到tools.jar。(注解:@Before(Tx.class))

2、注解加在controller中,AOP正常使用,注解也会生效。

想知道,注解加在service上和controller有什么区别?使用Aop.get()创建service。


评论区

JFinal

2021-02-04 18:04

1:service 默认的 proxy 依赖于 JDK 中的 tools.jar,如果你是 JRE 那么没有这个 tools.jar,需要添加配置改为使用 cglib:
me.setToCglibProxyFactory();

这里有详细说明:
https://jfinal.com/doc/4-8

2:controller 的 AOP 用的是最直接的递归调用,不依赖于任何第三方机制。在往期俱乐部视频中详细讲了这个设计

虽然 service 层与 controller 层的 AOP 用到了不同的实现方式,但对外开放的 API 以及一套使用方式是一样的,例如都是用的 @Before(...) 以及 Interceptor

云云

2021-02-04 19:40

明白了,感谢。再补充“张天笑jfinal分笑”的解答。

张天笑jfinal分笑(920950604) 18:24:01
@Cloud controller的反射调用开销是没办法抹掉的
所以controller不需要proxy

张天笑jfinal分笑(920950604) 18:25:06
从/index 映射到 index()方法, 只能通过 method.invoke()执行

张天笑jfinal分笑(920950604) 18:28:32
而 public void index() {
service.findXx(); // 这里是展开式的代码, 不是动态调用,
}
但实现aop 就需要动态调用, 动态调用就意味着反射,
为了抹调反射开销, jfinal使用动态编译子类的方式, 由这个子类去做平铺 展开式的调用

JFinal

2021-02-04 20:25

service 层的调用,你拿到手的是一个明确的类型,例如:
XxxService xxx = Aop.get(XxxService.class);
或者:
@Inject
XxxService xxx;

调用时是这样:
xxx.method(...);

而 controller 层的 action 调用方是 jfinal 框架,而 jfinal 框架在调用时拿到的仅仅是一个 url + para,一般是这样:
"/admin/article/delete?id=123"

通过 url 去对应一个对象上的方法的调用,与业务层是完全不同的,多少要有点反射的代码

所以,业务层的方案是无法消灭这里的反射的,controller 层的 AOP 改为使用业务层的模式也无法消除,所以还是保持原设计为好

原设计已将反射降到最低了,观察一下 action 的 java.lang.Method 的获取,只在初始化时进行一次

唯一的反射就只有 Method.invoke() 了,而这个也不太算上是反射了,性能是相当高的

热门反馈

扫码入社