咱们系统中有一段这样的代码,不少新来的同窗看起来比较蒙,这会不会报空指针啊! java
其实spring是支持这种基于接口实现类的直接注入的。spring
BeanInterface只是一个接口无方法。数组
package com.Autowired.ListMap; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * order:把实现类排序输出 只适合List * @author liu * */ @Order(2) @Component public class BeanImplOne implements BeanInterface { } package com.Autowired.ListMap; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Order(1) @Component public class BeanImplTwo implements BeanInterface { }
测试:eclipse
package com.Autowired.ListMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class BeanInvoke { @Autowired private List<BeanInterface> list; @Autowired private Map<String,BeanInterface> map; /** @Autowired默认为byType的 因此有两个相同类型的bean * 若是不使用 @Qualifier指定具体的bean就会抛出异常 * private BeanInterface beaninterface; */ @Autowired @Qualifier("beanImplOne") private BeanInterface beaninterface; public void say(){ System.out.println("list..."); if(null !=list &&0!=list.size()){ for(BeanInterface bean :list){ System.out.println(bean.getClass().getName()); } }else{ System.out.println("List<BeanInterface> list is null !!!!"); } System.out.println(); System.out.println("map..."); if(null !=map &&0!=map.size()){ for(Map.Entry<String, BeanInterface> m:map.entrySet()){ System.out.println(m.getKey()+" "+m.getValue().getClass().getName()); } }else{ System.out.println("Map<String,BeanInterface> map is null !!!!"); } System.out.println("-------------------------"); if(null !=beaninterface){ System.out.println(beaninterface.getClass().getName()); }else{ System.out.println("beaninterface is null !!!"); } } } package com.Autowired.ListMap; import org.junit.Test; import com.imooc.test.base.UnitTestBase; public class TestListMap extends UnitTestBase{ public TestListMap(){ super("classpath*:spring-beanannotation3.xml"); } @Test public void test(){ BeanInvoke bean=super.getBean("beanInvoke"); bean.say(); } }
配置文件:测试
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package="package com.Autowired.ListMap;"></context:component-scan> </beans>
输出结果:spa
2017-6-4 15:38:26 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@58a17083: startup date [Sun Jun 04 15:38:26 CST 2017]; root of context hierarchy 2017-6-4 15:38:26 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from URL [file:/E:/myeclipse/workspace/Spring2/bin/spring-beanannotation3.xml] 2017-6-4 15:38:27 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring list... 2017-6-4 15:38:27 org.springframework.context.support.AbstractApplicationContext doClose 信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@58a17083: startup date [Sun Jun 04 15:38:26 CST 2017]; root of context hierarchy com.Autowired.ListMap.BeanImplTwo com.Autowired.ListMap.BeanImplOne map... beanImplOne com.Autowired.ListMap.BeanImplOne beanImplTwo com.Autowired.ListMap.BeanImplTwo ------------------------- com.Autowired.ListMap.BeanImplOne
Spring吧bean放入了List中 那个这个顺序怎么控制呢指针
在实现类中加入@Order(value) 注解便可 ,值越小越先被初始化越先被放入Listcode
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DependencyDescriptor, String, Set<String>,TypeConverter)
对于@Autowired声明的数组、集合类型,spring并非根据beanName去找容器中对应的bean,而是把容器中全部类型与集合(数组)中元素类型相同的bean构造出一个对应集合,注入到目标bean中。对应到上问配置文件中,就是把容器中全部类型为java.lang.String的bean放到新建的Set中,而后注入到Manager bean中。也就是把resourcePackage和resourceLoaction这两个String注入了,致使上面的输出结果。component