Spring自动装配Beans

自动装配有几种?

在Spring框架,可以用 auto-wiring 功能会自动装配Bean。要启用它,只需要在 < bean>定义“autowire”属性。

< bean id=“customer” class=“com.jkk.common” autowire=“byName” />

在Spring中,支持 5 自动装配模式。

  • no – 缺省情况下,自动配置是通过“ref”属性手动设定

< property name=“person” ref=“person” />

  • byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。依靠set方法

  • byType – 按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并 自动装配它。依靠set方法

  • constructor – 在构造函数参数的byType方式。

  • autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”。

类型(Type)自动装配

(类型相同,id-名字不同的定义多个会报错)

  1. Beans

两个Bean,person 和 ability.

package com.bai.common;
 
public class Person 
{
	private Ability ability;
	//...
}
package com.bai.common;
 
public class Ability 
{
	private String skill;
	//...
}
  1. Spring Wiring

    通常情况下,明确地装配 bean:

	
<bean id="person" class="com.bai.common.Person">
		<property name="ability" ref="invisible" />
	</bean>
	
	<bean id="invisible" class="com.bai.common.Ability" >
		<property name="skill" value="Invisible" />
	</bean>

输出

Person [ability=Ability [skill=Invisible]]

随着自动装配按类型启用后,可以保留ability属性未设置。Spring会发现相同的数据类型并自动装配它。

<bean id="person" class="com.bai.common.Person" autowire="byType" />
	
	<bean id="invisible" class="com.bai.common.Ability" >
		<property name="skill" value="Invisible" />
	</bean>
	
输出
	
Person [ability=Ability [skill=Invisible]]

如果你有两个Bean,都是类“ability”相同的数据类型

被报错

<bean id="person" class="com.bai.common.Person" autowire="byType" />
	
	<bean id="steal" class="com.bai.common.Ability" >
		<property name="skill" value="Steal" />
	</bean>
	
	<bean id="invisible" class="com.bai.common.Ability" >
		<property name="skill" value="Invisible" />
	</bean>
	
		输出
	
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
...
No unique bean of type [com.yiibai.common.Ability] is defined: 
expected single matching bean but found 2: [steal, invisible]; nested exception is 
org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No unique bean of type [com.yiibai.common.Ability] is defined: 
expected single matching bean but found 2: [steal, invisible]
	

在这种情况下,它会打出 UnsatisfiedDependencyException (未满足依赖)的错误消息。

注:在类型的自动装配模式,就必须确保只有Bean 只有一个唯一的数据类型声明

名称(Name)自动装配

如果一个bean的名称与其他bean属性的名称是一样的,那么将自动装配它。

  1. Beans

     这里有两个 beans, 分别是:customer 和 address.
    
package com.common;
 
public class Customer 
{
	private Address address;
	//...
}
package com.common;
 
public class Address 
{
	private String fulladdress;
	//...
}
  1. Spring 装配

通常情况下,您明确装配Bean,这样通过 ref 属性:

<bean id="customer" class="com.common.Customer" >
		<property name="address" ref="address" />
	</bean>
	
	<bean id="address" class="com.common.Address" >
		<property name="fulladdress" value="YiLong Road, CA 188" /> </bean>
	
		输出
	
Customer [address=Address [fulladdress=YiLong Road, CA 188]]

使用按名称启用自动装配,你不必再声明属性标记。只要在“address” bean是相同于“customer” bean 的“address”属性名称,Spring会自动装配它。

	
<bean id="customer" class="com.common.Customer" autowire="byName" />
	
	<bean id="address" class="com.common.Address" >
	<property name="fulladdress" value="YiLong Road, CA 188" /> </bean>
	
输出
	
Customer [address=Address [fulladdress=YiLong Road, CA 188]]

看看下面另一个例子,这一次,装配将会失败,导致bean “addressABC”不匹配“customer” bean的属性名称。

	
<bean id="customer" class="com.common.Customer" autowire="byName" />
	
	<bean id="addressABC" class="com.common.Address" >
		<property name="fulladdress" value="Block A 888, CA" />
	</bean>
	
输出
	
Customer [address=null]

Spring由构造方法自动装配

  1. Beans

这里有两个 beans, 分别是:developer 和 language

package com.common;

public class Developer {
	private Language language;

	public Developer(Language language) {
		this.language = language;
	}

	//...

}
package com.common;

public class Language {
	private String name;
	//...
}
  1. Spring装配

     通常情况下,你可以通过构造这样自动装配 Bean:
    
<bean id="developer" class="com.common.Developer">
		<constructor-arg>
			<ref bean="language" />
		</constructor-arg>
	</bean>
		
	<bean id="language" class="com.common.Language" >
		<property name="name" value="Java" />
	</bean>
	
		输出
	
Developer [language=Language [name=Java]]

随着自动装配用构造函数启用后,你可以不设置构造器属性。Spring会找到兼容的数据类型,并自动装配它。

<bean id="developer" class="com..common.Developer" autowire="constructor" />
		
	<bean id="language" class="com.common.Language" >
		<property name="name" value="Java" />
	</bean>
	
		输出
	
Developer [language=Language [name=Java]]

Spring使用@Autowired注解自动装配

启用@Autowired,

必须注册“AutowiredAnnotationBeanPostProcessor’,

  1. < context:annotation-config />
    添加 Spring 上下文和< context:annotation-config />在bean配置文件中。
<beans 
	//...
	xmlns:context="http://www.springframework.org/schema/context"
	//...
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	//...

	<context:annotation-config />
	//...
</beans>

完整版applicationContext.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"  
	xsi:schemaLocation="
	http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
	http://www.springframework.org/schema/aop   
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
	http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.1.xsd  
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	<!-- 开启注解 -->
	<context:annotation-config />
	<!-- 自动扫描(service)(dao) -->
	<context:component-scan base-package="com.gx.dao,com.gx.service">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
	</context:component-scan>
</beans>

@Autowired示例

  1. @Autowired setter 方法
public class Customer 
{
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
	
	@Autowired
	public void setPerson(Person person) {
		this.person = person;
	}
}
	
  1. @Autowired 构造方法
public class Customer 
{
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
	
	@Autowired
	public Customer(Person person) {
		this.person = person;
	}
}
	
  1. @Autowired 字段
import org.springframework.beans.factory.annotation.Autowired;

public class Customer 
{
	@Autowired
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
}

上面的例子会自动装配“PersonBean”到Customer的person属性。

执行它

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
    	
    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
    	
    }
}

输出

Customer [person=Person [name=YiibaiA], type=1, action=buy]

依赖检查

当Spring无法找到匹配的Bean装配,它会抛出异常。
可以通过 @Autowired 的“required”属性设置为false来禁用此检查功能。

@Autowired(required=false)
private Person person;

@Qualifier

@Qualifier注解我们用来控制bean应在字段上自动装配。

@Autowired
@Qualifier(“personA”)
private Person person;

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean 
class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
	
	<bean id="customer" class="com..common.Customer" />
		
	<bean id="personA" class="com.common.Person" >
		<property name="name" value="yiibaiA" />
	</bean>
	
	<bean id="personB" class="com.common.Person" >
		<property name="name" value="yiibaiB" />
	</bean>

</beans>
发布了162 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39088066/article/details/103293433