Spring Bean的自动注入

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

    使用autowire属性配置自动装配,autowire可以设置如下值:

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

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

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

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

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

byName规则

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

   <!-- 将 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()方法:

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 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>限制在自动装配范围之外。

猜你喜欢

转载自my.oschina.net/u/3697923/blog/1618961