本篇文章给大家分享的是有关春天中查找的方式有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
<强>单例的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(参数),春天中查找的方式有哪些