春天中查找的方式有哪些

  介绍

本篇文章给大家分享的是有关春天中查找的方式有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

<强>单例的A类

@ component   public  class  ClassA  {   ,@ autowired   ,private  ClassB  classB;      ,public  void  printClass (), {   System.out.println才能(“却;能够is  Class ,:,“, +,);   classB.printClass才能();   ,}   }

<>强非单例的B类

@ component   @Scope (value =, SCOPE_PROTOTYPE)   public  class  ClassB  {   public 才能;void  printClass (), {   ,,,System.out.println(“却;能够is  Class  B:,“, +,);   ,,}   }

这类里一个采用了默认的单例的范围,并依赖于B级,而B级的范围是原型,因此不是单例的,这时候跑个测试就看出这样写的问题:

@RunWith (SpringRunner.class)   @ContextConfiguration (classes =, {ClassA.class, ClassB.class})   public  class  MyTest  {   @ autowired才能   private 才能;ClassA  classA;      @Test才能   public 才能;void  simpleTest (), {   ,,,for  (int 小姐:=,0;,小姐:& lt;, 3;,我+ +),{   ,,,,,classA.printClass ();   ,,,}   ,,}   }

输出的结果是:

这是A类:ClassA@282003e1
这是B类:ClassB@7fad8c79
这是A类:ClassA@282003e1
这是B类:ClassB@7fad8c79
这是A类:ClassA@282003e1
这是B类:ClassB@7fad8c79

可以看的到,两个类的散列码在三次输出中都是一样. Class一个的值不变是可以理解的,因为它是单例的,但是B类的范围是原型却也保持散列码不变,似乎也成了单例?

产生这种的情况的原因是,类的范围是默认的singleton,因此上下文只会创建类的bean一次,所以也就只有一次注入依赖的机会,容器也就无法每次给甲级提供一个新的类B .

<强>不那么好的解决方案

要解决上述问题,可以对A类做一些修改,让它实现ApplicationContextAware。

@ component   public  class  ClassA  implements  ApplicationContextAware  {   private 才能;ApplicationContext  applicationContext;      public 才能;void  printClass (), {   ,,,System.out.println(“却;能够is  Class 答:,“,+,);   ,,,getClassB () .printClass ();   ,,}      public 才能;ClassB  getClassB (), {   ,,,return  applicationContext.getBean (ClassB.class);   ,,}      public 才能;void  setApplicationContext (ApplicationContext  applicationContext), throws  BeansException  {   ,,,this.applicationContext =, applicationContext;   ,,}   }

这样就能够在每次需要到B级的时候手动去上下文里找到新bean的。再跑一次测试后得到了以下输出:

这是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

可以看到类的哈希代码在三次输出中保持不变,而B类的却每次都不同,说明问题得到了解决,每次调用时用到的都是新的实例。

但是这样的写法就和春天强耦合在一起了,春天提供了另外一种方法来降低侵入性。

<强> @Lookup

春提供了一个名为@Lookup的注解,这是一个作用在方法上的注解,被其标注的方法会被重写,然后根据其返回值的类型,容器调用BeanFactory的getBean()方法来返回一个bean。

@ component   public  class  ClassA  {   public 才能;void  printClass (), {   ,,,System.out.println(“却;能够is  Class 答:,“,+,);   ,,,getClassB () .printClass ();   ,,}      @Lookup才能   public 才能;ClassB  getClassB (), {   ,,,return 零;   ,,}   }

可以发现简洁了很多,而且不再和春季强耦合,再次运行测试依然可以得到正确的输出。
被标注的方法的返回值不再重要,因为容器会动态生成一个子类然后将这个被注解的方法重写/实现,最终调用的是子类的方法。

使用的@Lookup的方法需要符合如下的签名:

& lt;公共| protected>,[摘要],& lt; return-type>, theMethodName(参数),

春天中查找的方式有哪些