观察如下JavaBean
public class Student {
private String name;
private int age;
private School school;
private Dog dog;
private Address address;
}
如果一个类中依赖多个引用类型的成员变量,那么配置文件会比较繁琐,配置代码如下所示:
<bean id="s" class="com.xyr.demo02.Student">
<property name="name" value="隔壁老王"/>
<property name="age" value="30"/>
<!-- 引用类型的显示注入 -->
<property name="school" ref="school"/>
<property name="dog" ref="dog"/>
<property name="address" ref="address"/>
</bean>
其实针对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。但是需要按照指定的规则来设置, 根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType:根据类型自动注入
(1) byName方式自动注入
java类中引用类型的属性名(private School school)和Spring容器中(配置文件)<bean id="school">的id名称一样且数据类型是一致的,这样的容器中的bean,Spring能够自动赋值给引用类型.
语法:
<bean id="对象名称" class="对象所对应类的全限定名称" autowire="byName">
简单类型属性赋值
引用类型属性赋值可以不配置
</bean>
示例代码
<!-- 声明Student类对象 -->
<bean id="stu" class="com.xyr.demo04.Student" autowire="byName">
<property name="name" value="小李飞刀"/>
<property name="age" value="30"/>
<!--<property name="school" ref="school"/>-->
</bean>
<!-- 声明School类对象-->
<bean id="school" class="com.xyr.demo04.School">
<property name="schoolName" value="江西南昌大学"/>
<property name="schoolAddress" value="湖北"/>
</bean>
上述配置中,id为stu的bean标签中添加autowire属性值为byName方式注入,即可省略引用类型手动注入.Spring会根据Student类中的School类型的变量名称去查找配置文件中id为school的对象,如果找到并且类型一致,则完成自动注入,如果没找到注入失败,但是不会抛异常,只是属性值为null.原理图如下所示:
(2) byType方式自动注入(按照类型注入)
Java类中引用类型的数据类型(private School school)和Spring容器中(配置文件)<bean class="com.xyr.Student">的class属性是同源关系的,这样的bean能够注入给引用类型
同源关系主要有以下三种情况:
1. Java类中引用类型的数据类型和bean的class属性值是一样的.
2. Java类中引用类型的数据类型和bean的class属性值是父子类关系的.
3. Java类中引用类型的数据类型和bean的class属性值是接口和接口实现类的关系的.
语法:
<bean id="对象名称" class="对象所对应类的全限定名称" autowire="byType"> 简单类型属性赋值 引用类型属性赋值可以不配置</bean>
示例代码
<!-- 声明Student类对象 -->
<bean id="stu" class="com.xyr.demo05.Student" autowire="byType">
<property name="name" value="鸣人"/>
<property name="age" value="30"/>
<!--<property name="mySchool" ref="mySchool"/>-->
</bean>
<!-- 声明School类对象-->
<bean id="mySchool" class="com.xyr.demo05.School">
<property name="schoolName" value="天津美术学院"/>
<property name="schoolAddress" value="天津"/>
</bean>
上述配置中,id为stu的bean标签中添加autowire属性值为byType方式注入,即可省略引用类型手动注入.Spring会根据Student类中的School类型去查找配置文件中class属性值为com.xyr.demo05.School类型的对象,如果找到,则完成自动注入,如果没找到注入失败,但是不会抛异常,只是属性值为null.原理图如下所示:
接着我们来演示同源关系中的父子类关系.这里我们新建一个School类的子类PriamrySchool类,代码如下所示:
package com.xyr.demo05;
public class PrimarySchool extends School {}
xml配置文件如下所示:
<!-- 声明Student类对象 -->
<bean id="stu" class="com.xyr.demo05.Student" autowire="byType">
<property name="name" value="鸣人"/>
<property name="age" value="30"/>
</bean>
<!-- 声明PrimarySchool类对象-->
<bean id="primarySchool" class="com.xyr.demo05.PrimarySchool">
<property name="schoolName" value="天津实验小学"/>
<property name="schoolAddress" value="天津"/>
</bean>
重新运行程序,依然可以完成父子类关系的自动注入,如下图所示:
最后我们演示一下接口和接口实现类的同源关系,这里我们用之前的三层架构的作业来演示.
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" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册dao对象到Spring容器中-->
<bean id="mysqlDao" class="com.xyr.dao.impl.UserDaoImpl"/>
<!-- 注册service对象到Spring容器中-->
<bean id="userService" class="com.xyr.service.impl.UserServiceImpl" autowire="byType"> <!-- set方式将dao对象依赖注入到 userService对象中-->
<!--<property name="dao" ref="oracleDao"/>-->
</bean>
</beans>
测试代码如下所示:
public class AppTest {
@Test
public void test(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = ctx.getBean("userService", IUserService.class);
// 模拟数据库中的数据
User user = new User();
user.setName("西门吹雪");
user.setAge(25);
userService.register(user);
}
}
运行结果如下所示:
注意:
通过类型注入需要注意一点,就是当容器中存在多个同源类型的bean对象时,那么不仅不会注入成功,还会抛出异常.
xml配置如下所示:
<!-- 注册dao对象到Spring容器中-->
<bean id="mysqlDao" class="com.xyr.dao.impl.UserDaoImpl"/>
<!-- 注册Oralce dao对象到Spring容器中-->
<bean id="oracleDao" class="com.xyr.dao.impl.UserDaoImpl2"/>
<!-- 注册service对象到Spring容器中-->
<bean id="userService" class="com.xyr.service.impl.UserServiceImpl" autowire="byType">
<!-- set方式将dao对象依赖注入到 userService对象中-->
<!--<property name="dao" ref="oracleDao"/>-->
</bean>
异常如下所示:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in class path resource [applicationContext.xml]: Unsatisfied dependency expressed through bean property 'dao'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.xyr.dao.IUserDao' available: expected single matching bean but found 2: mysqlDao,oracleDao
总结: 在bytype方式的自动注入中,在xml配置文件中声明bean只能存在一个满足条件的,多余的都是错误的.
本文暂时没有评论,来添加一个吧(●'◡'●)