Edw*_*rew 4 java lazy-loading spring-boot
我的问题是,在调用 API 之前我需要获取身份验证令牌。必须在应用程序启动时调用 api。然而,我遇到了麻烦,因为两个调用是同时进行的,因此在进行 api 调用之前产生了没有身份验证令牌的错误。
我基本上需要 tokenUtilityClass 在实例化 Paypal 类之前创建令牌。我已经尝试过 @Preconstruct 和 @Lazy 注释,但两者都不适合我。
我有一个 validToken 的布尔值,一旦创建身份验证令牌,该值将返回 true。
这就是我的 Springboot 配置文件的样子
@Autowired
private TokenUtilityClass tokenUtilityClass;
@Bean ResourceConfig resourceConfig() {
return new ResourceConfig().registerClasses(Version1Api.class); }
@PostConstruct
public void postConstruct() {
tokenUtilityClass.tokenTimer();
}
@DependsOn("TokenUtilityClass")
@ConditionalOnProperty(name ="tokenUtilityClass.validToken", havingValue ="true")
@Lazy
public Paypal eventPublisherBean() {
return new Paypal();
}
Run Code Online (Sandbox Code Playgroud)
有人会对仅在生成身份验证令牌后初始化 Paypal 类有任何想法吗?
所有帮助将不胜感激
您声明的内容不起作用:
@DependsOn("TokenUtilityClass")
@ConditionalOnProperty(name ="tokenUtilityClass.validToken", havingValue ="true")
@Lazy
Run Code Online (Sandbox Code Playgroud)
因为tokenUtilityClass.validToken它不是一个属性,而是一个 bean 方法,而
ConditionalOnProperty需要一个属性。
有人会对仅在生成身份验证令牌后初始化 Paypal 类有任何想法吗?
具体来说,您无法直接使用 Spring 来实现它,因为一旦依赖项中的其他 bean 需要这些 bean,就会立即实例化这些 bean。
但仅声明:
@Bean
@Lazy
public Paypal eventPublisherBean() {
return new Paypal();
}
Run Code Online (Sandbox Code Playgroud)
如果该 bean 从未用作其他 bean 的急切加载依赖项,而是在您合适的时候需要:在检索令牌之后,则可以工作。
要实现这一目标,您有两种方法:
1)不要使用依赖注入PayPal,而只使用bean工厂。
未经测试,但听起来符合@Lazyjavadoc :
如果 @Component 或 @Bean 定义中不存在此注释,则会发生急切初始化。如果存在并设置为 true,@Bean 或 @Component 将不会被初始化,直到被另一个 bean 引用或从封闭的 BeanFactory 显式检索。
因此,注入BeanFactory负责获取令牌的 bean 并在检索令牌后使用该工厂初始化 bean。
像这样的东西:
@Service
public class TokenUtility {
private BeanFactory factory;
public TokenUtility(BeanFactory factory){
this.factory = factory;
}
public Token retrieveToken(){
// call service to get the token
//...
// init the bean now -(it will also invoke its @PostConstruct method)
PayPal payPal = beanFactory.getBean(PayPal.class);
}
}
Run Code Online (Sandbox Code Playgroud)
2) BeanFactory 的更直接替代方案是将 bean 声明为惰性依赖项:
@Service
public class TokenUtility {
@Lazy
@Autowired
Paypal paypal;
public Token retrieveToken(){
// call service to get the token
//...
// init the bean by invoking any method on that
paypal.init();
}
}
Run Code Online (Sandbox Code Playgroud)
我刚刚创建了一个非常基本的项目(Java 11)来测试: https: //github.com/ebundy/lazy-init-spring-example/。
当你执行时spring-boot:run你应该得到:
2020-02-26 09:38:05.883 INFO 7002 --- [ main] osweb.context.ContextLoader :根 WebApplicationContext:初始化在 682 毫秒内完成 TokenUtility init 状态代码=200 贝宝初始化
| 归档时间: |
|
| 查看次数: |
13108 次 |
| 最近记录: |