#java #spring
Вопрос:
У меня есть java-класс jar, который использует инъекцию поля spring, с пустым конструктором
public JarClass {
@Autowired
private JarField jarfield;
public JarClass() {}
}
Я хотел бы импортировать этот компонент в другой проект с инициализированным полем jarField
до сих пор я создавал класс в другом проекте, подобном этому
@Configuration
public class Config {
@Bean
public JarField jarField() {
return new JarField();
}
@Bean
public JarClass jarClass() {
return new JarClass();
}
}
если бы у меня был конструктор для внедрения зависимостей внутри JarClass, например
public JarClass {
private JarField jarfield;
this.jarField = jarField;
public JarClass(JarField jarfield) {
}
Я мог бы легко установить поле таким образом :
@Configuration
public class Config {
@Bean
public JarField jarField() {
return new JarField();
}
@Bean
public JarClass jarClass(@Bean JarField jarField) {
return new JarClass(jarField);
}
}
}
Но у меня нет для этого ни конструктора, ни сеттера.
Есть идея сделать мой JarField ненулевым без изменения JarClass удаленного класса ?
}
Ответ №1:
public JarClass {
@Autowired
private JarField jarfield;
public JarClass() {}
}
Приведенный выше класс приносит @Autowired
, поэтому он также должен быть пружинным бобом какого-либо типа @Component
, @Service
… Он не может быть создан с @Bean
помощью другого модуля, так как у него будет та же проблема с впрыском, с которой вы сталкиваетесь сейчас. Таким образом, мы в основном уверены, что у него есть какой-то тип аннотации, такой как @Component
Исходя из этого, вам вообще не нужно предоставлять
@Bean
public JarClass jarClass(@Bean JarField jarField) {
return new JarClass...
}
Обеспечьте только необходимую зависимость
@Bean
public JarField jarField() {
return new JarField();
}
и адаптируйте отсканированный пакет, чтобы включить пакет, в котором существует класс JarClass.
Затем весна сделает это волшебно, и она предоставит вам боб JarClass со всеми зависимостями.
Ответ №2:
Вы можете инициализировать компонент за другим компонентом, используя аннотацию dependsOn.
Кроме того, вам нужно инициализировать компонент вручную, вот так:
@Configuration
public class Config {
@Autowired
private ApplicationContext applicationContext;
@Bean
public JarField jarField() {
return new JarField();
}
@Bean
@DependsOn({"jarField"})
public JarClass jarClass() {
JarClass jarClass = new JarClass();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean( jarClass );
return jarClass;
}
}
Метод autowireBean будет обрабатывать поля и методы @Autowired. Если вам также необходимо вызвать постобработку (@PostConstruct и любые определенные BeanPostProcessors), также используйте:
factory.initializeBean( jarClass, "jarClass" );
Ответ №3:
Изменить:
public JarClass {
private JarField jarfield;
this.jarField = jarField;
public JarClass(JarField jarfield) {
}
В это:
public JarClass {
private final JarField jarfield;
@Autowired
public JarClass(JarField jarfield) {
this.jarField = jarField;
}
}
Комментарии:
1. Никакие модификации jarClass невозможны
2. Ну, вы можете создать новый класс, который расширит ваш JarClass и исправит нулевую часть.