2016-05-27 5 views
0

Как я могу исправить следующий пример для того, чтобы информировать Springapplication context где найти класс Application, конструктор помечается @Inject, но без вводя метод боб к ApplicationConfiguration аннотированный с @Bean, который возвращает экземпляр класса Application?Как приложение может сообщать контексту приложения Spring, где можно найти класс, конструктор которого аннотируется с помощью @Inject?

public class Application { 
    private final A a; 

    @Inject 
    public Application(A a) { 
     this.a = a; 
    } 

    public A getA() { 
     return a; 
    } 
} 

@Configuration 
public class ApplicationConfiguration { 
    @Bean 
    public A getA() { 
     return new A(); 
    } 
} 

public class A { 
} 

public class Start { 
    public static void main(String[] arguments) { 
     final ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); 
     final Application application = context.getBean(Application.class); 
     application.getA(); 
    } 
} 

Вы можете просмотреть исходный код проекта AtInject на GitHub.

Когда я бегу класс Start, весна жалуется, что не может найти класс Application:

May 27, 2016 4:49:55 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 
INFO: Refreshing org.spring[email protected]7eda2dbb: startup date [Fri May 27 16:49:55 EDT 2016]; root of context hierarchy 
May 27, 2016 4:49:55 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.opessoftware.atinject.application.Application] is defined 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:975) 
    at com.opessoftware.atinject.start.Start.main(Start.java:11) 
+0

Вы не объявили класс 'Application' как bean, что означает, что Spring ничего не знает о' Application', как его можно найти из 'ApplicationContext' – Jaiwo99

+0

Я понимаю вашу точку зрения, но невозможно аннотировать класс * с '@ Bean', только метод класса' @ Configuration', который возвращает экземпляр 'Application'. Я думаю, что Spring может найти конструкторы, которые аннотируются с помощью '@ Inject', но я не уверен, как проинструктировать Spring о том, как и где их найти. –

+0

вы можете отсканировать аннотацию, а затем создать bean-компонент вручную, но это и есть смысл сделать это. – Jaiwo99

ответ

1

После M. Deinum «s advice, я аннотированный класс Application с стереотипа @Component сказать Spring для лечения Application как фасоль и аннотированный класс ApplicationConfiguration с @ComponentScan для того, чтобы направить Spring, где найти компонент Application:

@Component 
public class Application { 
    private final A a; 

    @Inject 
    public Application(A a) { 
     this.a = a; 
    } 

    public A getA() { 
     return a; 
    } 
} 

@Configuration 
@ComponentScan({"me.derekmahar.atinject.application", "me.derekmahar.atinject.model"}) 
public class ApplicationConfiguration { 
    @Bean 
    public A getA() { 
     return new A("A1"); 
    } 
} 

Обратите внимание, что я также изменил класс A так, что он принимает имя:

public class A { 
    private final String name; 

    public A(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 
} 

Class Start теперь правильно печатает "Name of a1 is "A1".":

May 30, 2016 11:14:49 AM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 
INFO: Refreshing org.spring[email protected]7eda2dbb: startup date [Mon May 30 11:14:49 EDT 2016]; root of context hierarchy 
May 30, 2016 11:14:49 AM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
Name of a1 is "A1". 

Вы можете найти исходный код для решения в проекте AtInject на GitHub.