Skip to main content

忽略动态代理

标记到类上

任何类或者包上都可以通过标记 @IgnoreProxy 注解来达到不进行动态代理的目的。

@IgnoreProxy
public class CoreService {
....
}

此时在通过 AppContext 的方法创建这个 Bean 对象时候,无论我们是否配置了什么样的拦截器。这个类都不会被进行动态代理。

比如下面这个例子:

// 定义了一个全局拦截器,任何通过 Hasor 创建的 Bean 都会被 SimpleInterceptor 进行代理。
public class MyModule implements Module {
public void loadModule(ApiBinder apiBinder) throws Throwable {
//1.任意类
Matcher<Class<?>> atClass = Matchers.anyClass();
//2.任意方法
Matcher<Method> atMethod = Matchers.anyMethod();
//3.注册拦截器
apiBinder.bindInterceptor(atClass, atMethod, new SimpleInterceptor());
}
}

// 有一个 Service 标记了 IgnoreProxy 表示不参与动态代理
@IgnoreProxy
public class CoreService {
....
}

// 此时在通过 Hasor 创建这个对象时候即便存在全局拦截器也不会对 CoreService 产生任何效果。
AppContext appContext = Hasor.create().build();

appContext.getInstance(CoreService.class)

标记到包上

如果想控制更大范围内的忽略还可以新建一个 package-info.java 文件将其标记到包上。例如:

@IgnoreProxy
package net.hasor.core;

传递性

默认情况下 IgnoreProxy 的生效范围是其标注的位置以及其所有下属范围都会受到影响。

  • 标注到类上被标注的类型及其所有子类都不参与动态代理。
  • 通过 package-info.java 标注到包上之后:被标注的包下所有类型,及其子包下所有类型都不参与动态代理。
tip

@IgnoreProxy 生效的地方,即便是某些类型上指明了 @Aop 这样的注解,动态代理也会被忽略。

这种无差别的向下传播能力有时候并不是想要的,因此可以通过注解的 propagate 属性来控制是否禁止向下传播。这样就可以将忽略范围功效控制在一个可控的范围内。

@IgnoreProxy(propagate = false) // 设置 propagate 属性表示 IgnoreProxy 仅仅在当前类型有效,不影响子类
public class CoreService {
....
}

重写行为

重写行为的前提是我们已经有一个父类或者包上通过 @IgnoreProxy 标明了行为,但想在子类或子包中重新定义 @IgnoreProxy 的行为。

@IgnoreProxy() // 默认会影响到所有子类
public class FruitService {
....
}

// 父类声明了 IgnoreProxy, 禁止行为会传播到 AppleService
public class AppleService extends FruitService {
....
}

@IgnoreProxy(ignore = false) // 即便父类禁止了动态代理,子类依然可以通过 ignore 重写控制策略。
public class SubCoreService extends FruitService {
....
}