У меня есть один базовый интерфейс и две реализацийSpring autowire несколько Реализации услуг
public interface AnimalService
{
public void eat();
}
@Service("animalService")
@Transactional
public class AnimalServiceImpl implements AnimalService
{
@Override
public void eat()
{
System.out.println("i'm eating");
}
}
@Service("birdService")
@Transactional
public class BirdServiceImpl extends AnimalServiceImpl
{
public void fly()
{
System.out.println("i'm flying");
}
}
В моем основном методе попытаться вызвать эту реализацию две служб следующим образом:
public class test
{
@Autowired
private AnimalService animalService;
@Autowired
@Qualifier("birdService")
private AnimalService birdService;
public static void main(String[] args)
{
animalService.eat();
birdService.eat();
birdService.fly();
}
}
Это даст ошибку компиляции , так как birdService не может найти метод fly(). Тогда я подумал, может быть причина я autowire AnimalService вместо BirdServiceImpl, поэтому я изменить свой autowire код из этого:
@Autowired
@Qualifier("birdService")
private AnimalService birdService;
изменение:
@Autowired
private BirdServiceImpl birdService;
Но это даст мне ошибку времени выполнения, который «не может найти bean BirdServiceImpl». У меня есть много документов, некоторые говорят, что используйте @Resource. Но это не работает для меня. Некоторые говорят, что регистр в контексте Spring Context, в то время как вся моя регистрация бобов выполняется аннотацией. Я не хочу касаться контекста Весны.
Теперь Мое решение добавить новый интерфейс
public interface BirdService extends AnimalService
{
public void fly();
}
И пусть мой BirdServiceImpl реализовать этот интерфейс
public class BirdServiceImpl extends AnimalServiceImpl extends BirdService
{
public void fly()
{
System.out.println("i'm flying");
}
}
И моя главная изменить класс к этому:
public class test
{
@Autowired
private AnimalService animalService;
@Autowired
private BirdService birdService;
public static void main(String[] args)
{
animalService.eat();
birdService.eat();
birdService.fly();
}
}
Сейчас нормально . Но для меня это не идеально. Если я использую простой java, я могу просто написать один интерфейс и несколько реализаций. В основном методе я могу выбрать, какую реализацию использовать. Почему весной мне нужно создать новый интерфейс для каждой новой реализации, чтобы запустить мою программу.
Я хочу знать, есть ли лучший подход для моего сценария?
Ваш код, как есть, не будет работать с простой java. 'AnimalService' не имеет метода' fly' и независимо от того, что вы используете Spring или plain java (heck spring is java), он не найдет метод. Инъекция «BirdServiceImpl» завершится неудачно, потому что в зависимости от вашей конфигурации прокси-сервер будет создан для применения АОП. По умолчанию используются интерфейсы, поскольку вы реализуете интерфейс, поэтому ваш bean-компонент будет «AnimalService», но не одной из реализаций, который будет динамическим прокси-сервером, реализующим все интерфейсы. Который, imho, i, как и должно быть, как вы должны программировать на интерфейсы. –
Вы правы, если я использую простой java, все равно не могу вызвать fly(), если я не инициализирую bean-компонент таким образом: BirdServiceImpl birdService = new BirdServiceImpl(); – zzyclark