Spring自动装配

💪💪 🦆🦆🦆


共五种值可供选择,属于全局的设置

  • 复用的BeanA类
public class BeanA {
	private BeanB beanB;
	private BeanC beanC;

	public BeanB getBeanB() {
		return beanB;
	}

	public BeanA setBeanB(BeanB beanB) {
		this.beanB = beanB;
		return this;
	}

	public BeanC getBeanC() {
		return beanC;
	}

	public BeanA setBeanC(BeanC beanC) {
		this.beanC = beanC;
		return this;
	}
}
  • 复用的Test 类
import com.vi.springbean.BeanA;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Test {
	@org.junit.Test
	public void test() {
		String path = "spring-config.xml";
		BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(path));

		BeanA bean = beanFactory.getBean(BeanA.class);

		System.out.println("beanB  "+bean.getBeanB());
		System.out.println("beanC  "+bean.getBeanC());
	}
}

(一)default-autowire="byType"

  • 情况1
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="byType">


        <bean id="beanA" class="com.vi.springbean.BeanA"></bean>
	<bean id="beanBB" class="com.vi.springbean.BeanB"></bean>
	<bean id="beanC" class="com.vi.springbean.BeanD"></bean>
</beans>

运行结果:
beanB com.vi.springbean.BeanB@568bf312
beanC null

  • 情况2
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="byType">


	<bean id="beanA" class="com.vi.springbean.BeanA"></bean>
	<bean id="beanBB"  class="com.vi.springbean.BeanB"></bean>
	<bean id="beanCC" class="com.vi.springbean.BeanB"></bean>
</beans>
  • 运行结果:
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanA' defined in class path resource [spring-config.xml]: Unsatisfied dependency expressed through bean property 'beanB'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.vi.springbean.BeanB' available: expected single matching bean but found 2: beanBB,beanCC

说明可以找不到,但是不能存在多个类型一样的,匹配时与bean的id无关
多个类型一样可设置autowire-candidate="false",在自动装配时忽略此bean
多个类型一样可设置primary=“true”当前bean作为自动装备的值,直接忽略其他项

(二)default-autowire="byName"

  • 情况1
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="byName">


	<bean id="beanA" class="com.vi.springbean.BeanA"></bean>
	<bean id="beanB" class="com.vi.springbean.BeanB"></bean>
	<bean id="beanC2" class="com.vi.springbean.BeanB"></bean>
</beans>

运行结果:
beanB com.vi.springbean.BeanB@5d47c63f
beanC null

可以找不到,且可以存在多个同类型的

  • 情况2
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="byName">


	<bean id="beanA" class="com.vi.springbean.BeanA"></bean>
	<bean id="beanB" class="com.vi.springbean.BeanB"></bean>
	<bean id="beanC" class="com.vi.springbean.BeanD"></bean>
</beans>

运行结果:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in class path resource [spring-config.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.vi.springbean.BeanD' to required type 'com.vi.springbean.BeanC' for property 'beanC'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.vi.springbean.BeanD' to required type 'com.vi.springbean.BeanC' for property 'beanC': no matching editors or conversion strategy found
说明当通过name匹配到后,类型不能不符也是错误的

  • 情况3
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="byName">


<bean id="beanA" class="com.vi.springbean.BeanA"></bean>
<bean id="beanB" class="com.vi.springbean.BeanB"></bean>
<bean id="beanB" class="com.vi.springbean.BeanC"></bean>

</beans>

运行结果:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'beanB' is already used in this element
Offending resource: class path resource [spring-config.xml]

此时按照name去匹配的,bean的id和BeanA的中的属性 name一致即可注入,可以找不到,找到之后类型需要一致,xml中bean id的值需保证唯一性

(三)default-autowire="constructor"

类似于 byType,是根据构造方法里面的参数类型自动注入的

  • 更改后的BeanA
package com.vi.springbean;

public class BeanA {
	private BeanB beanB;
	private BeanC beanC;

       //显式的无参构造
       public BeanA() {
	}

        //仅有一个参数的构造
	public BeanA(BeanB beanB) {
		this.beanB = beanB;
	}

         //两个参数
	public BeanA(BeanB beanB, BeanC beanC) {
		this.beanB = beanB;
		this.beanC = beanC;
	}


	public BeanB getBeanB() {
		return beanB;
	}

	public BeanC getBeanC() {
		return beanC;
	}
}

  • 情况1
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="default">

	<bean id="beanA" class="com.vi.springbean.BeanA">
		<constructor-arg>
			<ref bean="beanB"></ref>
		</constructor-arg>
		<constructor-arg>
			<ref bean="beanC"></ref>
		</constructor-arg>
	</bean>


	<bean id="beanB" class="com.vi.springbean.BeanB">
		<property name="str" value="Hellow Spring"/>
	</bean>
	<bean id="beanC" class="com.vi.springbean.BeanC"></bean>
	<bean id="beanD" class="com.vi.springbean.BeanD"></bean>
</beans>

运行结果:
beanB com.vi.springbean.BeanB@341b80b2
beanC com.vi.springbean.BeanC@55a1c291

  • 情况2
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd"
	   default-autowire="default">

	<bean id="beanA" class="com.vi.springbean.BeanA">
		<constructor-arg>
			<ref bean="beanB"></ref>
		</constructor-arg>
	</bean>

	<bean id="beanB" class="com.vi.springbean.BeanB">
		<property name="str" value="Hellow Spring"/>
	</bean>
	<bean id="beanC" class="com.vi.springbean.BeanC"></bean>
	<bean id="beanD" class="com.vi.springbean.BeanD"></bean>
</beans>

运行结果:
beanB com.vi.springbean.BeanB@8e0379d
beanC null

1.bean id需要保证唯一性
2需与构造函数的参数匹配(类型个数匹配,顺序无所谓
必须有一个能与构造参数的类型全匹配,否则报错

(四)default-autowire="default" == default-autowire="no"

不使用自动装配

others

  • tip1
<!--除此之外,还可以在beans元素中指定,支持模式字符串,如下所有以abc结尾的Bean都被排除在自动装配之外-->
<beans default-autowire-candidates="*abc"></beans>
  • tip2
    byType注入时,当类型一致可以用index="数字",下标从0开始,匹配构造函数的参数

有错误,请大佬指导,我是菜鸟一小小只

posted @ 2019-12-27 22:03  VVII  阅读(190)  评论(0)    收藏  举报