2015-11-13 2 views
1

Я реализует BeanFactoryPostProcessor и я пытаюсь извлечь бин имен классов:Spring имя класса определения компоненты является нулем при использовании JavaConfig

@Component 
public class MyFactory implements BeanFactoryPostProcessor{ 

@Override 
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
    String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); 
    for (String name : beanDefinitionNames) { 
     BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name); 

     // 'null' when using JavaConfig, 'java.lang.String' when using XML 
     System.out.println(beanDefinition.getBeanClassName()); 
    } 

} 

} 

Когда я устанавливаю мои бобы с помощью XML, я получаю класс имя без каких-либо проблем:

<bean id="arbitraryString" class="java.lang.String"/> 

<bean class="com.test.MyFactory"/> 

Однако, когда я использую JavaConfig и определить боб там (простая строка для демонстрационных целей), имя класса будет нулевым:

@Bean 
public String arbitraryString() { 
    return "the bean definition class name will be null"; 
} 

Я пробовал искать это и не мог понять, что я делаю что-то неправильно или это ожидаемое поведение. Я не делаю ничего другого в своем основном методе, но загружаю контекст (будь то XML или config class).

+0

Вы пробовали поставлять имя компонента в аннотации? '@Bean (name =" произвольныйString ")' –

+0

Возможный дубликат: http://stackoverflow.com/questions/17155539/spring-bean-getting-confused Это, по-видимому, ожидается поведение – pandaadb

+0

@MichaelMurray просто попытался сейчас, все еще получая ноль. – Ozilophile

ответ

1

Я изучил его немного, и я думаю, что знаю, что может быть проблемой (не уверен, прав ли я, или если я объясню это правильно). Однако это, по-видимому, проблема:

Определение bean-компонентов в вашем классе JavaConfig вызывает инициализацию этого класса к весне. Однако порядок здесь важен, я думаю:

Он подберет ваш конфигурационный класс, извлечет все аннотированные методы @Bean и создаст эти объекты.

Теперь я считаю, что «корневой компонент», о котором вы говорите, является классом реализации, если вы создаете экземпляр класса. Это кажется естественным, но между весенним XML и весной javaconfig существует суматоха.

В XML:

Все бобы определяются как классы. Они создаются путем вызова конструктора этого класса.

В JavaConfig:

Компонент больше не является автономным боба. Он рассматривается как фасоль. Таким образом, у компонента нет класса корневого компонента, у него есть фабричный компонент и фабричный метод. Как бы вы установили корневой класс из определения метода? Вы можете установить корневой компонент как класс, но это не будет выполняться в большинстве классов. Фабрика может возвращать любую реализацию возвращенного класса, поэтому во время создания объекта BeanDefinition отсутствует корневой компонент.

Это можно заметить, отметив статическую конфигурацию appconfig (заводские методы). Теперь нет фабричного компонента, поскольку в момент проверки класса конфигурации он не создается. Это означает, что весна будет использовать CGI для создания реализации, которая является корневым компонентом. Это, однако, не корневой компонент, который вы ожидаете. Например, в моем тесте:

com.*.*.AppConfig$$EnhancerBySpringCGLIB$$1d5cc574 

Это результат, который я получаю при создании статических компонентов.

Таким образом, в общей сложности:

JavaConfig действует как фабрика, поэтому фасоль создан не известно, в то время формируется определение.

Xml четко определен, класс реализации явно установлен, поэтому предоставляется корневой компонент.

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

Я надеюсь, что помогает :)

- Артур

Edit: Конечная нота, это ожидаемое поведение :)

+0

Вы также можете увидеть это, распечатав свой компонент конфигурации. Конфигурации необходимо создать, вызвав конструктор. Поэтому ясно, что будет реализовывать компонент реализации, поэтому класс (усиленный CGI) является корневым компонентом. В моем случае: appConfig: Root bean: class [com. *. *. AppConfig $$ EnhancerBySpringCGLIB $$ 1d5cc574] – pandaadb