Как использовать @Autowired для динамического внедрения реализации как фабричного шаблона - PullRequest
5 голосов
/ 20 апреля 2011

Я довольно новичок в Sprint и использую Spring 3.x и roo1.1.1 для своего приложения.

У меня есть несколько реализаций интерфейса, который будет @Autowired в другие классы.Я мог бы только решить, с какой реализацией работать во время выполнения.Это должно быть достигнуто с помощью фабричного шаблона.

public interface SomeInterface {
    public void doSomething();
}

Реализация 1.

public class SomeOb implements SomeInterface {
    public void doSomething() {
        //Do something for first implementation here
    }
}

Реализация 2.

public class SomeOtherOb implements SomeInterface {
    public void doSomething() {
        //Do something for first implementation here
    }
}

Теперь в моей службе мне нужно этоAutowired, как

@Service 
public class MyService {

   @Autowired
   SomeInterface ob;
   //Rest of the code here

}

1) Логика выбора реализации для Autowired - только известная среда выполнения, поэтому я не могу использовать аннотацию @Qualifier для ее определения.2) Я попытался создать FactoryBean, например

public class SomeFactoryBean implements FactoryBean<SomeInterface> {
@Override
public SomeInterface getObject() throws Exception {
    if(/*Somecondition*/) {
        return new SomeOb();
    } else
        return new SomeOtherOb();
}

@Override
public Class<? extends SomeInterface> getObjectType() {
    if(/*Somecondition*/) {
        return SomeOb.class;
    } else
        return SomeOtherOb.class;
}

@Override
public boolean isSingleton() {
    return false;
}
}

. В applicationContext.xml у меня есть упомянутый тег.

Когда я запускаю веб-сервер, я сталкиваюсь с ошибкой вроде

No unique bean of type [com.xxxx.xxxx.SomeInterface] is defined: expected single matching bean but found 3: [xxxx, xxxxxxx, xxxxFactory]

Может кто-нибудь, пожалуйста, помогите мне решить эту проблему.Если я не делаю это правильно, пожалуйста, направьте меня, чтобы сделать это правильно.

Спасибо и признателен за любую помощь, jjk

Ответы [ 2 ]

3 голосов
/ 20 апреля 2011

Спасибо за предложение.Я смог решить проблему с помощью коллеги.Что я делал не так

  1. У меня была реализация SomeInterface с @Service.Так что это было обнаружено пружинным сканером и добавлено в bean-компонент.
  2. Во время проб и ошибок я удалил аннотацию @Component из реализации FactoryBean.

После внесения этих измененийработал как шарм.

0 голосов
/ 20 апреля 2011

верните true из isSingleton (), если вам нужна только одна реализация компонента для данного экземпляра вашего приложения

Но я ставлю под сомнение ваш дизайн.

Я бы всегда использовал файлы свойств для переключения реализаций, подобных этой. Однажды мне пришлось реализовать интеграцию CAPTCHA для сайта. Мы создавали прототипы с помощью API-интерфейсов JCaptcah и ReCAPTCHA. Я создал новый интерфейс, который содержал только необходимые нам функции, а затем создал реализации для обоих API. Используя заполнители в файле конфигурации Spring и профилях Maven, мы могли бы отключить класс реализации во время компиляции или развертывания, например, mvn jetty: run -DcaptchaImpl = recaptcha или -DcaptchaImpl = jcaptcha.

Не зная задачи, которую вы хотите выполнить, трудно дать больше советов.

...