控制反转,也叫DI——依赖注入,让调用类的控制权转交给容器来做。解除调用类的某一个接口对于实现类的依赖。
Spring支持构造函数注入和属性注入。
Spring容器,通过配置文件或者注解来描述类与类之间的依赖关系,自动的完成类的初始化和依赖注入的工作、
Spring设计了一个Resoursce接口,提供了更强的底层资源访问的能力,该接口拥有对于不同资源类型的实现类
BeanFactory是Spring框架的核心接口,提供了高级Ioc的配置机制,使得管理不同类型的java对象成为可能
ApplicationContext在BeanFactory的基础上,提供了更多面向应用 的功能,几乎所有场合都可以直接使用ApplicationContest而不是更加底层的BeanFactory。
BeanFactory是一个通用的类工厂,可以创建和管理各种类的对象,这些被创建的对象成为Bean。
在Spring中,装配Bean主要有一下的几种方式:
1,自动装配bean
1)在要装配的Bean声明前加注解 @Compoent,@Compment(“id_name”) 可以为Bean主动地指定id,或者使用named(“”)也可以
2)@ComponentScan 主动启动扫描,装配Bean,扫描的是同一个包下的所有类的带@Compoent注解的类。也可以使用xml启动注解的扫描
<context:component-scan base-package=""/>
3)@autowired 自动注入,可以在构造器或者方法上放。自动注入如果找到了多个可用的类型、或者找不到都会报错,因此要注意自动装配的歧义性。与@Inject相同,只不过前者是Spring中特有的注解
@ComponentScan(basepackage=“”)指定扫描的基础包,可以指定多个包,@ComponentScan (basePackages={“packA”,”packB”})。可以使用 basePackageClasses 参数代替基础包,这样对应的类或接口所在的包就会作为扫描的基础包,当然可以指明多个类接口,指定多个包。但是接口或类名称总可能被修改,可以考虑在包中创建一个用来进行扫描的空标记接口,不涉及业务逻辑,也就不会修改了。
@autowired(required=false) 意味着如果找不到bean注入到这个方法里面的话,也不会报出异常
@Component("g") //声明bean public class group { person leader; @Autowired //自动注入 public group(person leader) { this.leader = leader; } public void action(){ System.out.println(leader.info); } } //标明为配置类并且开启自动扫描 @Configuration @ComponentScan public class autoConfig { } //使用上下文引用这个Bean AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(autoConfig.class); group g=ctx.getBean(group.class); g.action();
2,JAVAConfig显式装配
单独建立一个类来进行装配,在类之前加上注解@Configuration,@Configuration注解表明这个类是一个配置类 ,包含在Spring应用上下文中如何创建bean的细节
对于每一个bean,在这个类中增加一个方法使用@bean进行注解,方法名字就是这个bean的ID,也可以使用@bean中的name的方法来指定Id的名字。
在这个时候,所有的被定义的Bean都是POJO,不需要注解。只需要一个配置类就可以了
@Configuration @ComponentScan(basePackageClasses = ComFace.class) public class autoConfig { @Bean public person getPerson(){ return new person("lz",12,"shuai"); } @Bean("g") //指定Bean的id public group getgGroup(person p){ //指定Bean之间的依赖关系——方法1 return new group(p); } @Bean("g") public group getgGroup(){ //指定Bean之间的依赖关系——方法2,注意引用的是定义person的Bean时所使用的方法 return new group(getPerson()); } }
带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例 ,就是说,你看到上面的那些return,其实可以在前面增加很多的处理方式。
3,使用xml文件进行装配
在XML文件的头部需要声明多个XML模式(XSD) 文件。
声明一个Bean<bean id= class=>
注入bean
1) 构造器注入bean
可以使用<constructor-arg>元素或者c命名空间
<bean class="com.A" c:b-ref="comD"/> <bean class="com.A" c:b-ref="comD"/> <bean class="com.A" > <constructor-arg ref="comD"></constructor-arg> </bean>
使用c命名空间的时候,把构造器的参数带带xml文件里面了,这就不太安全,玩意有人把构造器参数的名字改掉了,就不行了。可以选择使用_0、_1、_2这样的方式来指代,甚至于如果只有一个参数,直接使用_就可以了,例如。
<bean class="com.A" c:argname-ref="comD"/> //使用变量名 <bean class="com.A" c:_0-ref="comD"/> //使用代号 <bean class="com.A" c:_-ref="comD"/> //只有一个参数,可以忽略代号
下面重点介绍字面量的引入:
<bean class="Test.T2"> <constructor-arg value="A"></constructor-arg> <constructor-arg value="B"></constructor-arg> </bean> <bean class="Test.T2" c:s1="A" c:s2="B"></bean> <bean class="Test.T2" c:_0="A" c:_1="B"></bean>
很简单,ref就是使用id对bean进行引用,value就是直接引入字面值(c空间下,直接等号)
到目前为止,constructor-arg与c命名空间是等价的,但是c命名空间不能装配集合。
<bean class="Test.T2"> <constructor-arg> <list> <value>1</value> <value>2</value> <value>3</value> <value>4</value> <value>5</value> </list> </constructor-arg> </bean>
可以使用List/Set ,可以使用value/ref进行处理
属性的注入使用的是property和p命名空间,使用方法跟构造器注入是完全一样的。
p命名空间和c命名空间一样,不能使用集合,但是可以通过<util:list>util命名空间来实现,在外面通过<util:list>创建一个list,然后在p命名空间中来引用、
//p命名空间使用util来装配集合 <bean class="autoBean.group" id="g1" p:list-ref="ll"></bean> <util:list id="ll"> <value>12</value> <value>12</value> <value>12</value> </util:list>