0

Я могу получить функциональность репозитория, работающую изнутри main(), но нигде больше.Автообновленные репозитории имеют нулевое значение, кроме main()

Из всего, что я читал, это, кажется, что-то делать с @Autowired членов Я пытаюсь использовать создается за пределами «контекста» Spring или «контейнер.

Типичным виновника другие люди, кажется, чтобы придумать, нужно использовать «новый» для создания объекта, который выходит за рамки области Spring, но я сделал все, что мог, чтобы все, что полагалось на то, что было @Autowired, создано самой весной.

У меня есть следующий простой метод oneOff() внутри моего метода main() для печати первых 10 имен, которые при запуске работают как ожидалось:

@SpringBootApplication 
public class Application extends SpringBootServletInitializer { 

    @Autowired 
    private AppointmentServlet appointmentServlet; 

    @Autowired 
    private IAppointmentRepository appointmentRepository; 

    @Autowired 
    private IStaffMemberRepository staffMemberRepository; 

    @Autowired 
    private IStaffMemberRepository clientRepository; 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); 
     Application app = context.getBean(Application.class); 
     app.oneOff(); 
    } 

    @Bean 
    public ServletRegistrationBean servletRegistrationBean() { 
     return new ServletRegistrationBean(appointmentServlet,  "/AppointmentManager/NextAppointment"); 
    } 

    private void oneOff() { 
     System.out.println("\n=================== Starting lookup ==================="); 
     try { 

     int limit = 10; 
     for (int i = 0; i < limit; i++) { 
      StaffMember member = staffMemberRepository.findAll().get(i); 
      String firstName = member.getFirstName(); 
      String lastName = member.getLastName(); 
      if (firstName == null || firstName.equals("UNKNOWN") || firstName.isEmpty()) { 
       limit++; 
       continue; 
      } 
      System.out.println("Staff member: " + firstName + " " + lastName); 
     } 
    } catch (NullPointerException ex) { 
     System.out.println("NPE: Lookup failed"); 
    } System.out.println("==================== Ending lookup ==================="); 
} 

}

Который производит:

=================== Starting lookup =================== 
Staff member: JOSE BEJARANO 
Staff member: KARIMAH ABDUL-AZIZ 
Staff member: CONNIE ABED 
Staff member: WALID ABI-SAAB 
Staff member: BARRY ABRAHAM 
Staff member: JENNA ACEYCEK 
Staff member: DANIEL ADAMCZ YK 
Staff member: TYMOTEUSZ ADAMCZYK 
Staff member: ELIZABETH ADAMS 
Staff member: ERIN ADAMS 
==================== Ending lookup =================== 

Однако, когда я называю дубликат метода, который просто вставил в мой класс сервлета, хранилища никогда не получить экземпляр, и я получаю NullPointerExceptions.

Класс сервлета:

@Component 
public class AppointmentServlet extends SpeechletServlet { 

    @Autowired 
    private AppointmentSpeechlet appointmentSpeechlet; 

    public AppointmentServlet() { 
     this.setSpeechlet(appointmentSpeechlet); 
    } 

} 

Speechlet класс, где фактически используются хранилищами:

метод
@Component 
public class AppointmentSpeechlet implements Speechlet { 

    @Autowired 
    private IAppointmentRepository appointmentRepository; 

    @Autowired 
    private IStaffMemberRepository staffMemberRepository; 

    @Autowired 
    private IClientRepository clientRepository; 

    @Override 
    public SpeechletResponse onIntent(final IntentRequest request, final Session session) throws SpeechletException { 
     oneOff(); 
    } 
} 

OneOff() еще раз:

private void oneOff() { 
    System.out.println("\n=================== Starting lookup ==================="); 
    try { 

    int limit = 10; 
    for (int i = 0; i < limit; i++) { 
     StaffMember member = staffMemberRepository.findAll().get(i); 
     String firstName = member.getFirstName(); 
     String lastName = member.getLastName(); 
     if (firstName == null || firstName.equals("UNKNOWN") || firstName.isEmpty()) { 
      limit++; 
      continue; 
     } 
     System.out.println("Staff member: " + firstName + " " + lastName); 
    } 
    } catch (NullPointerException ex) { 
     System.out.println("NPE: Lookup failed"); 
    } System.out.println("==================== Ending lookup ==================="); 
} 

ответ

1

Вы добавили в свой @Component сервлет-класс, но это не делает его управляемым Spring компонентом. Фактически, контейнер сервлетов (например, Tomcat) создает экземпляр класса сервлета и управляет экземпляром вашего класса сервлета, и он ничего не знает о Spring - поэтому ваш сервлет не создается как компонент Spring и, следовательно, автоустановка не работает.

Лучшим решением было бы использовать Spring Web MVC и написать класс @Controller вместо написания собственного сервлета. Если вы не можете этого сделать, вы можете использовать WebApplicationContextUtils для поиска контекста приложения Spring из своего сервлета, в котором вы можете искать весенние бобы (вместо того, чтобы их автоустанавливать в сервлете).

+0

Большое вам спасибо за это! То, что вы сказали, имеет прекрасный смысл, и мне потребовалась бы вечность, чтобы разобраться в себе. Я собираюсь опробовать ваши предложения, и я обязательно верну свои результаты. –

+0

@MikeMedina Если ваша цель - создать веб-сервис REST с Spring Boot, то это супер-легко с Spring Data JPA и Spring Data REST; см., например, это руководство: [Доступ к данным JPA с помощью REST] (https://spring.io/guides/gs/accessing-data-rest/) – Jesper

+0

Я разрабатываю бэкэнд веб-службы для умения Amazon Alexa, который требует что я использую их реализацию «SpeechletServlet» –