Внедрение весенней загрузки унаследованного класса

Я разрабатываю основную библиотеку java, в которой изменения сведены к минимуму, она содержит класс Foo, где Foo используется интерфейсом spring rest и автоматически подключается к остальному интерфейсу.

Мне нужно расширить Foo, чтобы переопределить один из его методов, вызываемых Foo.init(), чтобы немного изменить инициацию.

Мой FooExtend автоматически связан с другим классом в моем проекте, и я надеюсь, что эти два объекта будут ссылаться на один и тот же объект, объект FooExtend, но на данный момент я получаю один объект Foo и один FooExtend. Как мне это решить? Примеры ниже

@Component
public class Foo{
  @PostConstruct
  private void init() {
    startStuff();
  }

  protected void startStuff(){
    //Stuff done here
  }
}

@Component
public class FooExtend extends Foo{
  @PostConstruct
  private void init() {
    //Nothing is done here
  }

  @Override
  protected void startStuff(){
    //Different altered stuff is done here
  }
}

person Daniel Eineving    schedule 11.05.2017    source источник
comment
Я не уверен, что понимаю вашу проблему. У вас есть два bean-компонента, один bean-компонент с именем foo и один bean-компонент с именем fooExtend. Мне кажется, что вы должны иметь возможность использовать @Qualifier(fooExtend) или @Qualifier(foo) вместе с @Autowired поверх ссылки на Foo для автоматического подключения того или иного.   -  person BartoszMiller    schedule 11.05.2017


Ответы (2)


Попробуйте исключить класс Foo из сканирования

@ComponentScan(value = {'your.package.here'}, excludeFilters = {
  @ComponentScan.Filter(classes = { Foo.class })
})
person StanislavL    schedule 11.05.2017
comment
Я не могу вносить подобные изменения в Foo, поскольку он находится в пакете Core, и поэтому его не следует изменять для уничтожения для других проектов в зависимости от ядра. Или я должен положить его в свой собственный пакет где-нибудь? - person Daniel Eineving; 11.05.2017
comment
Вы должны добавить это в свою весеннюю загрузку (не в основной пакет). Поэтому, когда ваше приложение запускается, bean-компонент для Foo.class не создается. - person StanislavL; 11.05.2017
comment
Не могу заставить это работать, я, вероятно, слишком дружен в своем определении класса, но при этом я получаю эту ошибку: java.lang.IllegalArgumentException: An error occurred while processing a @ComponentScan ANNOTATION type filter: class com.companyname.projectname.core.Foo is not assignable to interface java.lang.annotation.Annotation - person Daniel Eineving; 11.05.2017
comment
Проблема с этим решением заключается в том, что у ядра есть собственный @ComponentScan, включая Foo. Таким образом, это исключение, вероятно, только сломается, поскольку ничего не найдет. - person Daniel Eineving; 11.05.2017
comment
Если вы не хотите регистрировать Foo в контексте Spring, это правильное решение. Попробуйте указать тип фильтра: @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, значение=Foo.class). Однако требуется, чтобы Foo и FooExtend находились в разных пакетах, чтобы FooExtend был зарегистрирован в вашем контексте Spring. - person BartoszMiller; 11.05.2017

Есть 2 возможных ответа в зависимости от ваших требований:

1) Вы хотите зарегистрировать Foo и FooExtend в своем контексте Spring. В таком случае вы можете использовать аннотацию @Qualifier для внедрения того или иного экземпляра:

@Autowired
@Qualifier("fooExtend")
Foo foo;

2) Вы хотите зарегистрировать FooExtend только в контексте Spring.

@ComponentScan(value = {'your.package.here'}, excludeFilters = {
 @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class))
}

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

person BartoszMiller    schedule 11.05.2017
comment
Решение 2 было бы предпочтительным, но Foo находится в Spring Context Core, из-за чего он все еще загружается. - person Daniel Eineving; 11.05.2017
comment
Это зависит от того, как вы сканируете/регистрируете bean-компоненты из своей основной библиотеки. Если это @ComponentScan, вы можете исключить его с помощью фильтра. - person BartoszMiller; 11.05.2017
comment
Я не смог заставить его работать. Это дало мне следующую ошибку: java.lang.IllegalArgumentException: An error occurred while processing a @ComponentScan ANNOTATION type filter: class com.companyname.projectname.core.Foo is not assignable to interface java.lang.annotation.Annotation - person Daniel Eineving; 11.05.2017