Совместное использование экземпляра класса в приложении весенней загрузки - PullRequest
0 голосов
/ 14 мая 2019

У меня есть определенный класс, используемый для взаимодействия со службой, которая требует инициализации. В жизненном цикле приложения единственное место, в котором это имеет смысл, - это запуск приложения, поскольку остальная часть весеннего приложения не может работать без него. У меня была идея сделать это:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        try {
            MyRequiredService mrs = new MyRequiredService();
            mrs.connect(); // This will throw if it fails
            run(MyApplication.class, args);
        } catch(MyException e) {
            System.out.println("Failed to connect to MyRequiredService!");
        }
    }
}

Это запустит службу и попытается подключиться, но у меня есть одна большая проблема. Как мне пройти этот класс вокруг приложения? Мне нужны его функции в конечных точках службы, которые я пишу.

Я не увидел ничего очевидного, и при поиске "передачи экземпляра класса в приложении весенней загрузки" возникает куча не связанных между собой тем.

Есть ли умный, чистый способ сделать это при весенней загрузке? Я прошу прощения за надуманный пример. Названия службы достаточно уникальны, и я не хотел нарушать какие-либо соглашения.

Ответы [ 3 ]

2 голосов
/ 14 мая 2019

Вы можете заставить Spring сделать это за вас. Во-первых, вам нужно аннотировать свой класс с помощью @Service, поэтому Spring подберет его при сканировании классов.

Затем определите метод init() и аннотируйте его с помощью @PostConstruct. Spring создаст экземпляр вашего MyRequiredService класса и вызовет init()

@Service
public class MyRequiredService {

    @PostConstruct
    public void init() {
        connect();
    }

    public void connect() {
        // ...
    }
}

Вы могли бы вызвать connect() из конструктора, но я не люблю определять объекты, которые могут выбрасывать исключения из конструктора.

И затем, вы можете использовать MyRequiredService в каком-то другом классе, добавив его через аннотацию @Autowired:

@Component
public class MyOtherClass {
    private final MyRequiredService service;

    public MyOtherClass(final MyRequiredService service) {
        this.service = service;
    }

    // Other methods here.
}

Это имеет тот же общий эффект, что вы пытаетесь сделать выше. В случае сбоя MyRequiredService приложение не запустится.

0 голосов
/ 14 мая 2019

класс реализует BeanFactoryPostProcessor, который инициализируется перед обычным бином

@Configuration
public class MyRequiredService implements BeanFactoryPostProcessor, 
PriorityOrdered, InitializingBean {

@Override
public int getOrder() {
    return Integer.MIN_VALUE;
}

public void connect() {
    // ...
}


@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

}


@Override
public void afterPropertiesSet() throws Exception {
        connect();
}

}

0 голосов
/ 14 мая 2019

Сделайте это бобом. Тогда он будет в ApplicationContext, который затем вы можете передать желаемым другим классам через конструктор

@Configuration
public class ApplicationConfiguration
{

    @Bean
    public MyRequiredService myRequiredService()
    {
        MyRequiredService mrs = new MyRequiredService();
        try {
            mrs.connect(); // This will throw if it fails
            return mrs;
        } catch(MyException e) {
            log.error("Failed to connect to MyRequiredService!");
            throw new IllegalStateException("MyRequiredService failed connection. Stopping startup");
        }
    }

    @Bean 
    public SomeOtherService someOtherService(MyRequiredService mrs) {
        return new SomeOtherService(mrs);
    }
}

ИМХО Вместо того, чтобы ловить ошибку и регистрировать ее. Я бы бросил его и остановил запуск приложения, но, чтобы не отставать от вашего примера, я добавил исключение throw IllegalStateException после журнала.

Делая это таким образом, Spring создаст ваш bean-компонент MyRequiredService в ApplicationContext, и вы увидите, что я добавил его в качестве параметра, необходимого для bean-компонента ниже. Весна схватит этот боб из ApplicationContext и подаст его в боб. Если Spring не находит bean-компонент в ApplicationContext, он выдаст ошибку и остановит запуск приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...