2.2.3 依赖注入
2.2.3.1 依赖注入之setter注入
(1)创建学生类Student
public class Student { private Integer id; private String name; private Integer age; private String sex; public Student() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } // toSting方法
(2)配置bean时为前属性赋值
<bean id="studentOne" class="com.atguigu.spring.bean.Student"> <!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 --> <!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关)--> <!-- value属性:指定属性值 --> <property name="id" value="1001"></property> <property name="name" value="张三"></property> <property name="age" value="23"></property> <property name="sex" value="男"></property> </bean>
(3)测试
@Test public void testDIBySet(){ ApplicationContext ac = new ClassPathXmlApplicationContext("spring-di.xml"); Student studentOne = ac.getBean("studentOne", Student.class); System.out.println(studentOne); }
2.2.3.2 依赖注入之构造器注入
(1)在Student类中添加有参构造
public Student(Integer id, String name, Integer age, String sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; }
(2)配置bean
<bean id="studentTwo" class="com.atguigu.spring.bean.Student"> <constructor-arg value="1002"></constructor-arg> <constructor-arg value="李四"></constructor-arg> <constructor-arg value="33"></constructor-arg> <constructor-arg value="女"></constructor-arg> </bean>
注意:
constructor-arg标签还有两个属性可以进一步描述构造器参数:
①index属性:指定参数所在位置的索引(从0开始)
②name属性:指定参数名
2.2.4 特殊值处理
(1)字面量赋值
什么是字面量?
int a = 10;
①声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a
的时候,我们实际上拿到的值是10。
②而如果a是带引号的:‘a’,那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。
所以字面量没有引申含义,就是我们看到的这个数据本身。
<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 --> <property name="name" value="张三"/>
(2)null值
<property name="name"> <null /> </property>
注意:以下写法,为name所赋的值是字符串null
<property name="name" value="null"></property>
(3)xml实体
<!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 --> <!-- 解决方案一:使用XML实体来代替 --> <property name="expression" value="a < b"/>
④CDATA节 <property name="expression"> <!-- 解决方案二:使用CDATA节 --> <!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 --> <!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 --> <!-- 所以CDATA节中写什么符号都随意 --> <value><![CDATA[a < b]]></value> </property>
2.2.5 为类类型属性赋值
2.2.5.1 创建相关的类
①创建班级类Clazz
public class Clazz { private Integer clazzId; private String clazzName; //有参,无参构造器 //Get/Set方法,toString
②修改Student类
public class Student { private Integer sid; private String name; private Integer age; private String gender; private Clazz clazz;//添加Clazz属性 //有参,无参构造器 //Get/Set方法,toString }
2.2.5.2 实现方式
(1)方式1:引入外部已声明的bean
①配置Clazz类型的bean:
<bean id="clazzOne" class="com.atguigu.spring.bean.Clazz"> <property name="clazzId" value="1111"></property> <property name="clazzName" value="财源滚滚班"></property> </bean>
②为Student中的clazz属性赋值:
<bean id="studentFour" class="com.atguigu.spring.bean.Student"> <property name="id" value="1004"></property> <property name="name" value="赵六"></property> <property name="age" value="26"></property> <property name="sex" value="女"></property> <!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 --> <property name="clazz" ref="clazzOne"></property> </bean>
(2)方式二:内部bean
<bean id="studentFour" class="com.atguigu.spring.bean.Student"> <property name="id" value="1004"></property> <property name="name" value="赵六"></property> <property name="age" value="26"></property> <property name="sex" value="女"></property> <property name="clazz"> <!-- 在一个bean中再声明一个bean就是内部bean --> <!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 --> <bean id="clazzInner" class="com.atguigu.spring.bean.Clazz"> <property name="clazzId" value="2222"></property> <property name="clazzName" value="远大前程班"></property> </bean> </property> </bean>
(3)方式三:级联属性赋值(一般不使用)
<bean id="clazzOne" class="com.atguigu.spring.bean.Clazz"> <property name="clazzId" value="1111"></property> <property name="clazzName" value="财源滚滚班"></property> </bean> <bean id="studentFour" class="com.atguigu.spring.bean.Student"> <property name="id" value="1004"></property> <property name="name" value="赵六"></property> <property name="age" value="26"></property> <property name="sex" value="女"></property> <!-- 一定先引用某个bean为属性赋值,才可以使用级联方式更新属性 --> <property name="clazz" ref="clazzOne"></property> <property name="clazz.clazzId" value="3333"></property> <property name="clazz.clazzName" value="最强王者班"></property> </bean>
2.2.6 为数组类型属性赋值
(1)修改Student类,在Student类中添加以下代码:
private String[] hobbies; // Get/Set方法
(2)配置bean
<bean id="studentFour" class="com.atguigu.spring.bean.Student"> <property name="hobbies"> <array> <value>跳舞</value> <value>唱歌</value> <value>蹦迪</value> </array> </property> </bean>
2.2.7 为集合类型属性赋值
2.2.7.1 为List集合类型属性赋值
(1)在Clazz类中添加以下代码:
private List<Student> students; // Get/Ste方法
(2)配置bean
<bean id="clazzTwo" class="com.atguigu.spring.bean.Clazz"> <property name="students"> <list> <ref bean="studentOne"></ref> <ref bean="studentTwo"></ref> <ref bean="studentThree"></ref> </list> </property> </bean>
注意:若为Set集合类型属性赋值,只需要将其中的list标签改为set标签即可
2.2.7.2 为Map集合类型属性赋值
(1)创建教师类Teacher:
public class Teacher { private Integer teacherId; private String teacherName; }
(2)在Student类中添加以下代码:
private Map<String, Teacher> teacherMap;
(3)配置bean
<bean id="teacherOne" class="com.atguigu.spring.bean.Teacher"> <property name="teacherId" value="10010"></property> <property name="teacherName" value="大宝"></property> </bean> <bean id="teacherTwo" class="com.atguigu.spring.bean.Teacher"> <property name="teacherId" value="10086"></property> <property name="teacherName" value="小宝"></property> </bean> <bean id="studentFour" class="com.atguigu.spring.bean.Student"> <property name="teacherMap"> // key:是字面量用key,是类类型用key-ref // value:是字面量用value,是类类型用value-ref <map> <entry key="10086" value-ref="teacherOne"></entry> <entry key="10010" value-ref="teacherTwo"></entry> </map> </property> </bean>
2.2.8 p命名空间
引入p命名空间后,可以通过以下方式为bean的各个属性赋值
<bean id="studentSix" class="com.atguigu.spring.bean.Student" p:id="1006" p:name="小明" p:clazz-ref="clazzOne" p:teacherMapref="teacherMap"> </bean>
2.2.9 引入外部属性文件
(1)加入依赖
<!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <!-- 数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.31</version> </dependency>
(2)创建外部属性文件
(3)引入属性文件
<!-- 引入外部属性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/>
(4)配置bean
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="url" value="${jdbc.url}"/> <property name="driverClassName" value="${jdbc.driver}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </bean>
(5)测试
@Test public void testDataSource() throws SQLException { ApplicationContext ac = new ClassPathXmlApplicationContext("springdatasource.xml"); DataSource dataSource = ac.getBean(DataSource.class); Connection connection = dataSource.getConnection(); System.out.println(connection); }