Spring Bean的自动注入

    Spring的自动装配可经过<beans/>元素的default-autowire属性指定,也可经过<bean>元素的autowire属性指定。自动装配能够指定到单独的Bean,同一个Spring容器中可让某些Bean使用自动装配,而另外一些Bean不使用自动装配。java

    使用autowire属性配置自动装配,autowire能够设置以下值:spring

    1)no:不使用自动装配。Bean依赖必须经过ref元素定义。也是Spring默认配置。app

    2)byName:根据属性名自动装配,BeanFactory查找容器中的所有Bean,找出其中id属性与属性同名的Bean来完成注入,若是没有找到匹配的Bean实列,则Spring不会进行注入。ide

    3)byType:根据属性类型自动装配。BeanFactory查找容器中的所有Bean,若是正好有一个与依赖属性类型相同的Bean,就自动注入这个属性;若是有多个相同类型的Bean,就会抛出一个异常;若是没有匹配的Bean,则什么都不会发生。测试

    4)constructor:与byType相似,区别是用于构造注入的参数。若是BeanFactory没有符合该Bean的构造器,则会注入异常。this

    5)autodetect:BeanFactory根据Bean内部结构,决定使用constructor或者byType。若是含有一个默认的构造器,就会应用byType。spa

byName规则

    byName规则是指经过名字注入依赖关系,仍是使用“人”与“斧子”的列子,假如Bean Chinese 包含setAxe()方法,而Spring中拥有ID为“axe”的Bean,这样Spring容器会将斧子axe注入到人Chinese中。code

<!-- 将 stoneAxe经过byName注入chinese中的axe属性-->
   <bean id="chinese" class="com.custle.spring.Chinese" autowire="byName"/>  
   <!--  将StoneAxe交给Srping管理 -->
   <bean id="axe" class="com.custle.spring.StoneAxe"/>

在Chinese类中定义setAxe()方法:component

package com.custle.spring;

public class Chinese implements Person {

	private Axe axe;
	
	//构造器注入所须要的斧子
	public Chinese(Axe axe) {
		this.axe = axe;
	}
	
	public Chinese() {
	}
	//注意该set方法后的名字与Bean中定义的ID为axe相同
	public void setAxe(Axe axe) {
		this.axe = axe;
	}

	@Override
	public void useAxe() {
		System.out.println(axe.chop());
	}

}

这样就经过byName属性将石斧注入到Chinese中。接下来看一下注解用法;xml

首先在xml文件中声明使用注解,即便用注解的包须要被扫描;

<?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/springcontext.xsd">
	<!-- 扫描使用注释的包 -->
	<context:component-scan base-package="com.custle.spring"/>
	<!-- 声明使用byName注入-->
    <bean id="chinese" class="com.custle.spring.Chinese" autowire="byName"/>  
</beans>

在StoneAxe类经过@Component(value="stone")注释将其交由Spring管理;

@Component(value="stone")
public class StoneAxe implements Axe {

	@Override
	public String chop() {
		return "使用石斧砍材";
	}
		
}

在Chinese中经过@Resource(name="stone")或者@Autowired、@Qualifier("stone")使用;

package com.custle.spring;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Chinese implements Person {
	
//	@Resource(name="stone") 或者直接使用该注释
	
	@Autowired
	@Qualifier("stone")
	private Axe axe;
	
	static{
		System.out.println("Chinese被实列化");
	}
	
	//构造器注入所须要的斧子
	public Chinese(Axe axe) {
		this.axe = axe;
	}
	
	public Chinese() {
	}
	
	public void setAxe(Axe axe) {
		this.axe = axe;
	}

	@Override
	public void useAxe() {
		System.out.println(axe.chop());
	}

}

测试代码:

public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-spring.xml");
		Chinese chinese = (Chinese)applicationContext.getBean("chinese");
		chinese.useAxe();
	}

控制台输出:

使用石斧砍材

在这里附带说一下使用@Resource注释的装配顺序:

    当@Resource后面没有任何内容时,默认使用byName的属性去匹配Bean,找不到Bean时再按照byType去匹配Bean;当指定了装配类型就按照指定的装配类型去匹配Bean,若没有找到匹配的Bean则会产生异常。

@Autowired和@Resource注释的区别:

    @Autowired默认使用byType方式去装配Bean,而@Resource是使用byName方式去装配Bean。@Resource是属于JAVA的注解,而@Autowired是属于Spring的注解。

byType规则

    byType规则,指根据类型匹配来注入依赖关系。假如Chinese实列有setAxe(Axe axe)方法,而Spring配置文件中拥有Axe类型的实列,则能够将Axe类型的实列注入到Chinese实列中。若Spring中不含有Axe类型的实列,也不会发生异常。可是当Spring容器中含有多个Axe类型的实列则会发生异常。

    现将配置类型放置全局中,全部该<beans>下的子元素<bean>都知足该装配方式:

<?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/springcontext.xsd"
    default-autowire="byType">
	<!-- 扫描使用注释的包 -->
	<context:component-scan base-package="com.custle.spring"/>  
</beans>

    因为使用了byType的配置方式,将StoneAxe交由Spring容器管理时,直接使用@Component便可,无须定义name;在Chinese实列中使用@Resource和@Autowired都可。

    在某些状况下,能够限制Bean做为自动装配的候选者,则可使用autowire-candidate="false"便可将该Bean限制在自动装配范围以外。或者在<beans>元素中使用default-autowire-candidates="false"便可将该<beans>下全部的子元素<bean>限制在自动装配范围以外。

相关文章
相关标签/搜索