Служба неправильно автоматически подключается — конфигурация на основе аннотаций

Я использую конфигурацию на основе аннотаций - вообще без XML.

Я все настроил, но не могу понять, почему OrderService не подключается автоматически и продолжает оставаться null. Класс ниже в самом низу — это тот, который показывает реальную проблему. Все остальные классы — это моя конфигурация.

У меня есть log4j в этом приложении, но я неопытен в этом. Есть ли способ зарегистрировать, какие пакеты/классы сканируются, чтобы определить, почему это не работает?

Служба заказов

@Service
public class OrderService extends GenericService<OrderDAO, Order> {
    @Autowired
    OrderDAO dao;
}

Конфигурация служб

@Configuration
public class Config {
    @Bean
    public OrderService orderService() {
        return new OrderService();
    }
}

Основная конфигурация

@Configuration
@ComponentScan(basePackages = {
        "com.production.api",

        //todo: may not need the rest of these
        "com.production.api.dao",
        "com.production.api.models",
        "com.production.api.requests",
        "com.production.api.requests.job",
        "com.production.api.resources",
        "com.production.api.resources.job",
        "com.production.api.services"
})
@Import({
        com.production.api.services.Config.class,
        com.production.api.dao.Config.class
})
@PropertySource(value= "classpath:/META-INF/application.properties")
@EnableTransactionManagement
public class Config {

Main.java

public static void main(String[] args) throws IOException {
    //process annotation configuration
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

    HttpServer httpServer = startServer();
    System.out.println(String.format("Jersey app started with WADL available at " + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...", BASE_URI, BASE_URI));
    System.in.read();
    httpServer.stop();
}

В чем проблема...

@Component
public class NewJobRequestHandler {

    public static Logger logger = Logger.getLogger(Logger.class.getName());

    //@todo Why isn't this autowiring?
    @Autowired
    OrderService orderService;

    public void instantiateOrderService() {
        //@todo remove this manual wiring
        orderService = (OrderService) ApplicationContextProvider.getApplicationContext().getBean("orderService");
    }

    public AuthenticatedApiResponse getResponse(AuthenticatedRequest<NewJobRequest> request) {
        instantiateOrderService();

person Webnet    schedule 28.02.2013    source источник
comment
Оба OrderService и NewJobRequestHandler находятся в пакетах в вашем @ComponentScan? Кроме того, вам не нужен @Bean для @OrderService. @Service уже идентифицирует его как компонент.   -  person Sotirios Delimanolis    schedule 28.02.2013
comment
Да, они оба в пакетах, которые находятся в @ComponentScan. Вы говорите, что мне не нужен файл конфигурации служб, потому что он помечен как @Service и сканируется?   -  person Webnet    schedule 28.02.2013
comment
Если это единственный боб, то да, именно об этом я и говорю.   -  person Sotirios Delimanolis    schedule 28.02.2013
comment
@SotiriosDelimanolis - Спасибо, я посмотрю на это, как только служба заработает.   -  person Webnet    schedule 28.02.2013


Ответы (1)


Проблема здесь в том, что ваша конфигурация и контекст Spring отделены от вашего стека Jersey/Grizzly. Вы ожидаете, что Джерси сможет получить beans из Spring, но он не знает, что Spring существует, его аннотации ничего для него не значат.

Вам нужно заменить свой сервлет Джерси на сервлет Spring Джерси и добавить ContextLoaderListener. Взгляните на этот пример о том, как подключить Джерси и весна. Я не уверен, как работает Grizzly, но если он похож на любой другой контейнер сервлетов, это должно работать.

Для log4j вы можете установить уровень корневого регистратора на INFO или DEBUG, и вы получите всевозможные операторы журнала из Spring.

person Sotirios Delimanolis    schedule 28.02.2013
comment
Я добавил, что ... Это выявило ошибку в Autowiring, так что похоже, что этот патч работает правильно. Однако теперь я получаю сообщение об ошибке Exception in thread "main" java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once при развертывании, несмотря на 1 обновление. - person Webnet; 28.02.2013
comment
Вы передаете контекст какому-либо методу? - person Sotirios Delimanolis; 28.02.2013
comment
Нет, но у меня есть служба, которая вручную подключается VendorService vendorService = (VendorService) ApplicationContextProvider.getApplicationContext().getBean("vendorService"); к другой части приложения. Но комментировать это не имеет никакого эффекта - person Webnet; 28.02.2013
comment
Это работает в каком-то контейнере? Или ваша точка входа Main? - person Sotirios Delimanolis; 28.02.2013
comment
Main — точка входа. Я использую Grizzly, поэтому он устанавливает контейнер http и все такое. - person Webnet; 28.02.2013
comment
Я не знаю, как работает Grizzly, но если вы собираетесь использовать DI Spring, вам придется получать все свои bean-компоненты из его контекста, а не генерировать их самостоятельно. Что касается вашего исключения, проверьте, где оно происходит, и идите по следу. - person Sotirios Delimanolis; 28.02.2013
comment
Это исходит от ctx.refresh(), которого вы предложили добавить. - person Webnet; 28.02.2013
comment
давайте продолжим это обсуждение в чате - person Sotirios Delimanolis; 28.02.2013
comment
Пожалуйста, взгляните на эту тему [1], там есть пример интеграции Jersey ‹-› Spring ‹-› Grizzly. [1] гризли .1045725.n5.nabble.com/ - person alexey; 01.03.2013