Предисловие
Эта статья в основном представляет соответствующий контент о поиске (впрыска метода) весной. Это обменивается вашей ссылкой и обучением. Я не скажу многое ниже. Давайте посмотрим на подробное введение вместе:
Это может произойти при использовании Spring: один синглтон-боб зависит от другой не-синглетонской бобов. Если вы просто используете автоматическую сборку для введения зависимостей, могут возникнуть некоторые проблемы, как показано ниже:
Класс А для Синглтона
@Componentpublic class classa {@autowired private classb classb; public void printClass () {System.out.println («Это класс A:» + this); classb.printclass (); }}Класс B для безжигания
@Component@scope (value = scope_prototype) public class classb {public void printclass () {System.out.println ("Это класс B:" + this); }} Здесь класс А принимает синглтонский объем по умолчанию и полагается на класс B. Объем класса B является прототипом, так что это не синглтон. В настоящее время вы можете увидеть проблему написания подобной степени после проведения теста:
@Runwith (springrunner.class) @contextconfiguration (classes = {classa.class, classb.class}) открытый класс mytest {@autowired private classa classa; @Test public void simpleStest () {for (int i = 0; i <3; i ++) {classa.printclass (); }}}Результатом вывода:
Это класс A: Classa@282003e1
Это класс B: classb@7fad8c79
Это класс A: Classa@282003e1
Это класс B: classb@7fad8c79
Это класс A: Classa@282003e1
Это класс B: classb@7fad8c79
Как видите, хэш -код обоих классов одинаковы в трех выходах. Понятно, что ценность класса A остается неизменной, потому что это синглтон, но объем класса B является прототипом, но также сохраняет хэш -код неизменным, который, похоже, стал синглтоном?
Причиной этой ситуации является то, что сфера действия класса А является одиночным по умолчанию, поэтому контекст создаст только один раз боб класса А, поэтому есть только один шанс вводить зависимости, и контейнер не может предоставлять класс А каждый раз новым классом B.
Не очень хорошее решение
Чтобы решить вышеуказанную проблему, вы можете внести некоторые изменения для класса A для реализации ApplicationContextAware.
@Componentpublic class classa реализует ApplicationContextAware {private ApplicationContext ApplicationContext; public void printClass () {System.out.println («Это класс A:» + this); getClassb (). printClass (); } public classb getClassb () {return applicateContext.getBean (classb.class); } public void setApplicationContext (ApplicationContext ApplicationContext) Throws BeanSexception {this.ApplicationContext = ApplicationContext; }}Таким образом, вы можете вручную найти новую фасоль в контексте каждый раз, когда вам нужно ходить в класс B. После проведения еще одного теста я получил следующий вывод:
Это класс A: com.devhao.classa@4df828d7
Это класс B: com.devhao.classb@31206beb
Это класс A: com.devhao.classa@4df828d7
Это класс B: com.devhao.classb@3e77a1ed
Это класс A: com.devhao.classa@4df828d7
Это класс B: com.devhao.classb@3ffcd140
Вы можете видеть, что хэш -код класса A остается неизменным в трех выходах, в то время как класс B каждый раз отличается, что показывает, что проблема была решена, и новый экземпляр используется каждый раз, когда он называется.
Тем не менее, этот метод написания тесно связан с пружиной, а пружина обеспечивает еще один способ снизить инвазивность.
@Искать
Spring предоставляет аннотацию под названием @lookup, которая представляет собой аннотацию, которая работает на методе. Метод, помеченный им, будет переопределен. Затем, в соответствии с типом его возвращаемого значения, контейнер вызывает метод GetBean () BeanFactory, чтобы вернуть боб.
@Componentpublic class classa {public void printclass () {System.out.println («Это класс A:» + this); getClassb (). printClass (); } @Lookup public classb getClassb () {return null; }} Можно найти, что это намного проще и больше не сильно связано с пружиной. Запуск теста снова может получить правильный выход.
Возвратное значение аннотированного метода больше не является важным, поскольку контейнер динамически генерирует подкласс, а затем переписывает/реализует аннотированный метод, и наконец -то вызван метод подкласса.
Используемый метод @lookup должен соответствовать следующей подписи:
<public | Protected> [Abstract] <Возвратный тип> TheThodName (без аргументов);
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.