То, что вы объявили, не может работать:
@DependsOn("TokenUtilityClass")
@ConditionalOnProperty(name ="tokenUtilityClass.validToken", havingValue ="true")
@Lazy
, потому что tokenUtilityClass.validToken
не свойство, а метод bean, а ConditionalOnProperty
ожидает свойства.
У кого-нибудь возникнут идеи об инициализации класса Paypal только после того, как будет создан токен аутентификации.
Конкретно, вы не можете достичь этого напрямую с помощью Spring, потому что компоненты создаются, как только они требуются другими компонентами в их зависимостях.
Но заявив, что:
@Bean
@Lazy
public Paypal eventPublisherBean() {
return new Paypal();
}
может сработать, если этот bean-компонент никогда не используется в качестве загружаемой зависимости других bean-компонентов, а скорее требуется в удобное для вас время: после того, как токен был
Чтобы добиться этого, у вас есть два способа:
1) не использовать внедрение зависимостей для экземпляра PayPal
, а использовать исключительно фабрику бобов.
Не проверено, но звучит как @Lazy
javado c:
Если эта аннотация отсутствует в определении @Component или @Bean, будет выполнена активная инициализация. Если он присутствует и установлен в значение true, @Bean или @Component не будут инициализированы до тех пор, пока на него не будет ссылаться другой компонент или он явно не будет извлечен из включающего BeanFactory.
Поэтому вставьте BeanFactory
в компонент, ответственный за получение токен и использовать эту фабрику для инициализации 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);
}
}
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();
}
}
Я только что создал очень простой c проект (Java 11) для проверки: https://github.com/ebundy/lazy-init-spring-example/.
Когда вы выполните spring-boot:run
, вы должны получить:
2020-02-26 09:38:05.883 INFO 7002 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 682 ms
TokenUtility init with status code=200
PayPal init