九、Component 的自动代理(AOP)
Solon 组件的动态代理和自动代理功能,要求类和函数 “能继承”、“能重写”,即:
- 类是 public 的,且不能是 final(kotlin 则是要 open)
- 函数是 public,且不能是 final(kotlin 则是要 open)
更多的边界参考:《动态代理的本质与边界》
1、当扫描组件时,发现有AOP需求时会启用动态代理
@Component
public class UserService{
@Tran
public void addUser(User user){ }
}
这个组件,因为有 public 函数使用了 @Tran 拦截处理的注解(算是有AOP需求)。所以会自动启用动态代理
2、当组件里没有AOP需求时,不会启用动态代理
@Component
public class UserService{
@Note("添加用户")
public void addUser(User user){ }
}
这个组件,没有用到拦截处理的注解。则不会启用动态代理。
3、怎么样算是有AOP需求?
很简单,在容器里能找到一个注解的对应拦截器的(例:context.beanInterceptorGet(Xxxx.class) != null
) 或者注解里带有环绕注解的(例:@Around(XxxInterceptor.class)
)。比如刚刚在"切面与环绕拦截(AOP)"看到的,注册了 Tran 注解的拦截器的:
context.beanInterceptorAdd(Tran.class, new TranInterceptor());
那使用 @Tran
注解的组件,就是有AOP需求了:
@Component
public class UserService{
@Tran
public void addUser(User user){ }
}
也就是会自动启用动态代理了。
4、所谓动态代理?
就是在“原始类”的外面动态包了一层“代理类”。“代理类”扩展自“原始类”,并重写了所有函数。用户在调用时,自然会先经过“代理类”,“代理类”则会偷偷的把注解关联的拦截处理放进来。具体可见:《动态代理的本质与边界》。