Аннотация Spring @Async не создает новый поток

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

Я использую в качестве руководства для реализации этой пружины: https://spring.io/guides/gs/async-метод/

Это мой класс RestController с объявлением класса @Autowired

@RestController
public class RTCEntitiesRESTController {

    @Autowired
    private RTCEntitiesProcessor rtcEntitiesProcessor;

    @RequestMapping(value = "/refresh", method = RequestMethod.POST)
    public void refreshEntities() {
        rtcEntitiesProcessor.getStatus().start();
    }

    @RequestMapping(value = "/status", method = RequestMethod.GET)
    public @ResponseBody
    AbstractState getStatus() {
        return rtcEntitiesProcessor.getStatus();
    }

}

public class Ready extends AbstractState {

    private static final Logger LOGGER = LogManager.getLogger(Ready.class);

    @Override
    @Scheduled(fixedDelay = 600000)
    public void start() {
        context.setStatus(new InProgress());
        LOGGER.info("Starting process");
        LOGGER.info(Thread.currentThread().getName());
        context.processData();
    }

    @Override
    public String getStatus() {
        return "ready";
    }

}

Это класс @Component

@Component
public class RTCEntitiesProcessor {

    private static final Logger LOGGER = LogManager.getLogger(RTCEntitiesProcessor.class);

    private RTCEntitiesController entitiesController;
    private List<RTCRoleDefinition> roleDefinitions;
    private List<RTCUser> users;
    private AbstractState status;
    @Value("${rtcServer.timeBetweenExecutionsInMinutes}")
    private long timeBetweenExecutions;

    public RTCEntitiesProcessor(RTCEntitiesController entitiesController) {
        this.entitiesController = entitiesController;
        this.roleDefinitions = new ArrayList<RTCRoleDefinition>();
        this.users = new ArrayList<RTCUser>();
        status = new Ready();
    }

    @PostConstruct
    public void passContext() {
        status.setContext(this);
    }

    @Async
    public void processData() {
        try {
            getNewEntities();
            LOGGER.info(Thread.currentThread().getName());
            Thread.sleep(10000);
            status.block();
        } catch (Exception e) {
            LOGGER.info("Error while processing entities", e);
            status.fail();
        }
    }

    private void getNewEntities() throws InterruptedException {
        List<RTCRoleDefinition> newRoleDefinitions = new ArrayList<RTCRoleDefinition>();
        List<RTCUser> newUsers = new ArrayList<RTCUser>();
        for (RTCProjectArea projectArea : entitiesController.getProjectAreas()) {
            projectArea.addAreas(entitiesController.getTeamAreas(projectArea));
            processArea(projectArea, null);
            newRoleDefinitions.addAll(projectArea.getRoles());
            newUsers = mergeUsers(newUsers, projectArea.getMembers());
            for (RTCTeamArea rtcTeamArea : projectArea.getAreas()) {
                newRoleDefinitions.addAll(rtcTeamArea.getRoles());
                newUsers = mergeUsers(newUsers, rtcTeamArea.getMembers());
            }
        }
        this.roleDefinitions = newRoleDefinitions;
        this.users = newUsers;
    }

Это класс @SpringBootAplication

@SpringBootApplication
@EnableAsync
@EnableScheduling
public class MainController {

    private static final Logger LOGGER = LogManager.getLogger(MainController.class);

    @Value("${rtcServer.username}")
    private String username;
    @Value("${rtcServer.password}")
    private String password;
    @Value("${rtcServer.uri}")
    private String serverURI;

    public static void main(String[] args) {
        LOGGER.info("Running Spring Boot Application");
        SpringApplication.run(MainController.class, args);
    }

    @Bean
    public RTCHttpClient getClient() {
        return new RTCHttpClient(username, password, serverURI);
    }

}

Можете ли вы более конкретно рассказать о том, как ваш код «отказывается работать»?

Kai 18.02.2019 23:51

откуда context взялся в Ready классе?

Deadpool 19.02.2019 04:39

логи тоже могут нам помочь

Book Of Zeus 19.02.2019 05:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
868
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратите особое внимание на то, что аннотации @Async не работают, если они вызываются this. Итак, попробуйте автопроводить RTCEntitiesProcessor в своем Ready классе. Вы должны сделать Ready как @Component для этого

Чтобы понять, вы можете прочитать больше в https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-understanding-aop-proxy

Как это относится к вопросу? Вызов метода не вызывается этим

sechanakira 19.02.2019 10:58
public void passContext() { status.setContext(this); } настроить контекст в состоянии готовности. После этого вызовите метод состояния заданного контекста context.processData()
Andrey 19.02.2019 11:22

@Андрей Спасибо!! Я решил проблему, предоставив классу Read ссылку на bean-компонент RTCEntitiesProcessor, а затем я передал RTCEntitiesProcessor экземпляр готового bean-компонента (с ленивой аннотацией), и теперь он работает.

Leandro Farias 22.02.2019 13:50

Другие вопросы по теме