Хотел создать зависимости через application-Context.xml для ArrayList
Хотел создать зависимости через application-Context.xml для ArrayList через setter, но увы ошибка.
В чем может быть проблема?
Визуально не вижу ошибку, но практика говорит о другом.
package ua.vadym;
import org.springframework.beans.factory.annotation.Value;
import java.util.ArrayList;
import java.util.List;
public class MusicPlayer {
private List<Music> musicList = new ArrayList<>();
private String name;
private int volume;
public MusicPlayer() {
}
public void playMusic(List<Music>musicList) {
for (Music m : musicList) {
m.getSong();
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
public void setMusicList(List<Music> musicList) {
this.musicList = musicList;
}
}
Контекст
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="musicPlayer.properties"></context:property-placeholder>
<!-- Bean ClassickMusic-->
<bean id="classicalMusic"
class="ua.vadym.ClassicalMusic">
</bean>
<!-- Bean RockMusic-->
<bean id="rockMusic"
class="ua.vadym.RockMusic">
</bean>
<!-- Bean RapMusic-->
<bean id="rapMusic"
class="ua.vadym.RapMusic" ></bean>
<!-- Внедрение зависимости через Сеттер-->
<bean id="musicPlayer" class="ua.vadym.MusicPlayer">
<property name="musicList" >
<list>
<value type="ua.vadym.RapMusic">classicalMusic</value>
<ref bean="classicalMusic"></ref>
<value type="ua.vadym.RockMusic">rockMusic</value>
<ref bean="rockMusic"></ref>
<value type="ua.vadym.ClassicalMusic">rapMusic</value>
<ref bean="rapMusic"></ref>
</list>
</property>
</bean>
</beans>
Main
public class TestSpring {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("application-Context.xml");
MusicPlayer musicPlayer = context.getBean("musicPlayer", MusicPlayer.class);
RockMusic rockMusic = context.getBean("rockMusic", RockMusic.class);
ClassicalMusic classicalMusic = context.getBean("classicalMusic", ClassicalMusic.class);
RapMusic rapMusic = context.getBean("rapMusic", RapMusic.class);
List<Music> list = new ArrayList<>();
list.add(rockMusic);
list.add(classicalMusic);
list.add(rapMusic);
musicPlayer.playMusic(list);
System.out.println("Done");
context.close();
}
}
Ответы (1 шт):
У Вас явная ошибка при определении бина плеера
<bean id="musicPlayer" class="ua.vadym.MusicPlayer">
<property name="musicList" >
<list>
<value type="ua.vadym.RapMusic">classicalMusic</value>
<ref bean="classicalMusic"></ref>
<value type="ua.vadym.RockMusic">rockMusic</value>
<ref bean="rockMusic"></ref>
<value type="ua.vadym.ClassicalMusic">rapMusic</value>
<ref bean="rapMusic"></ref>
</list>
</property>
</bean>
С таким контекстом вы закономерно получаете Exception
сент. 19, 2022 8:53:10 AM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'musicPlayer' defined in class path resource [application-Context.xml]: Error converting typed String value for bean property 'musicList' with key [0]; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic': no matching editors or conversion strategy found
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'musicPlayer' defined in class path resource [application-Context.xml]: Error converting typed String value for bean property 'musicList' with key [0]; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:218)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:428)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1707)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1452)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at ua.vadym.TestSpring.main(TestSpring.java:10)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:76)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:209)
... 16 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
... 18 more
В котором вам явно говорят, что Спринг не может привести строку к объекту типа ua.vadym.RapMusic
Вот эта строка
Cannot convert value of type 'java.lang.String' to required type 'ua.vadym.RapMusic':
И вот строка в конфигурации из-за которой она возникла
<value type="ua.vadym.ClassicalMusic">rapMusic</value>
И у остальной музыки будет аналогичная ошибка.
- во-первых вы неправильно указываете значение объекта
- во-вторых это действие лишнее, потому что вам вообще не нужно создавать здесь значение.
Вы уже создавали эти объекты ранее
<!-- Bean ClassickMusic-->
<bean id="classicalMusic" class="ua.vadym.ClassicalMusic"></bean>
<!-- Bean RockMusic-->
<bean id="rockMusic" class="ua.vadym.RockMusic"></bean>
<!-- Bean RapMusic-->
<bean id="rapMusic" class="ua.vadym.RapMusic" ></bean>
Все что вам нужно будет сделать это просто сослаться на них в списке
<list>
<ref bean="classicalMusic"></ref>
<ref bean="rockMusic"></ref>
<ref bean="rapMusic"></ref>
</list>
Это все!..
application-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="musicPlayer.properties"></context:property-placeholder>
<bean id="classicalMusic" class="ua.vadym.ClassicalMusic"></bean>
<bean id="rockMusic" class="ua.vadym.RockMusic"></bean>
<bean id="rapMusic" class="ua.vadym.RapMusic" ></bean>
<bean id="musicPlayer" class="ua.vadym.MusicPlayer">
<property name="musicList" >
<list>
<ref bean="classicalMusic"></ref>
<ref bean="rockMusic"></ref>
<ref bean="rapMusic"></ref>
</list>
</property>
</bean>
</beans>
И из main'а вам стоит убрать эти строки
RockMusic rockMusic = context.getBean("rockMusic", RockMusic.class);
ClassicalMusic classicalMusic = context.getBean("classicalMusic", ClassicalMusic.class);
RapMusic rapMusic = context.getBean("rapMusic", RapMusic.class);
List<Music> list = new ArrayList<>();
list.add(rockMusic);
list.add(classicalMusic);
list.add(rapMusic);
musicPlayer.playMusic(list);
вы по сути повторно забираете эти зависимости и передаете их в плеер
У нас все это описано в конфигурации и сам Spring должен за нас это сделать.
К слову о плеере...
Вам стоит заменить реализацию метода playMusic()
(или добавить рядом перегруженный метод)
было
public void playMusic(List<Music>musicList) {
for (Music m : musicList) {
m.getSong();
}
}
Чтобы данный метод работал с внедренным свойством нужен такой
public void playMusic() {
for (Music m : musicList) {
m.getSong();
}
}
И точка входа получится такой:
package ua.vadym;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("application-Context.xml");
MusicPlayer musicPlayer = context.getBean("musicPlayer", MusicPlayer.class);
musicPlayer.playMusic();
System.out.println("Done");
context.close();
}
}
тестируем
все работает отлично
