SpringIOC第3弹-XML实现DI


  • 0x01_回顾:什么是DI?

  • 0x02_DI的实现3种方式

    • 通过set方法属性赋值

    • 通过有参构造方法属性赋值

    • 通过p名称空间和c名称空间给对象属性赋值

  • 0x03_特殊情况:注入空值和特殊符号

  • 0x04_Bean的引用

    • 写法1:外部引用

    • 写法2:内部引用

    • 写法3:级联引用bean

  • 0x05_集合注入


Spring XML实现DI

0x01_回顾:什么是DI?

DI就是Dependency Injection依赖注入。

应用程序代码从Ioc Container中获取依赖的Bean,注入到应用程序中,这个过程叫 依赖注入(Dependency Injection,DI) ; 所以说控制反转是通过依赖注入实现的,其实它们是同一个概念的不同角度描述。通俗来说就是IoC是设计思想,DI是实现方式

这里可以简单理解为DI就是对属性进行赋值。(现有IOC,对象的创建,才有DI,对象属性的赋值)

0x02_DI的实现3种方式

首先准备实体类:

package com.bones.bean;
/**
* @author : bones
* @version : 1.0
*/

public class User {
private Integer userid;
private String username;
private String password;

public User(Integer userid, String username, String password) {
System.out.println("allArgConstructor");
this.userid = userid;
this.username = username;
this.password = password;
}

public User() {
System.out.println("noArgConstructor");
}

public Integer getUserid() {
System.out.println("getUserid");
return userid;
}

public String getUsername() {
System.out.println("getUsername");
return username;
}

public String getPassword() {
System.out.println("getPassword");
return password;
}

@Override
public String toString() {
return "User{" +
"userid=" + userid +
", username='" + username + ''' +
", password='" + password + ''' +
'}';
}

public void setUserid(Integer userid) {
System.out.println("setUserid");
this.userid = userid;
}

public void setUsername(String username) {
System.out.println("setUsername");
this.username = username;
}

public void setPassword(String password) {
System.out.println("setPassword");
this.password = password;
}
}

通过set方法属性赋值

这个方法相当于:

User user = new User()
user.setXXX()

applicationContext.xml

<!--    通过set方法对属性进行赋值-->
<bean id="user2" class="com.bones.bean.User">
<property name="userid" value="1"/>
<property name="username" value="Amy"/>
<property name="password" value="111111"/>
</bean>

测试:

        //获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
User user2 = applicationContext.getBean("user2",User.class);
System.out.println(user2);

SpringIOC第3弹-XML实现DI

通过有参构造方法属性赋值

这个方法相当于:

User user = new User(2,"","");

applicationContext.xml中:

<!--    通过有参构造方法属性赋值-->
<bean id="user3" class="com.bones.bean.User">
<constructor-arg name="userid" value="2"/>
<constructor-arg name="username" value="Bob"/>
<constructor-arg name="password" value="222222"/>
</bean>

测试结果:

SpringIOC第3弹-XML实现DI

通过p名称空间和c名称空间给对象属性赋值

首先要在applicationContext.xml中启用p命名空间和c命名空间:(添加约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

SpringIOC第3弹-XML实现DI

在Bean标签中使用p命名空间:

<bean id="user4" class="com.bones.bean.User" p:userid="3" p:username="Cathy" p:password="333333">
</bean>

使用c命名空间:

<bean id="user5" class="com.bones.bean.User" c:userid="4" c:username="Dobby" c:password="444444">
</bean>

p命名空间和set方法给属性赋值类似,其实算是一种简化的方法,而c命名空间和调用有参的构造方法给属性赋值类似,也算是一种简化的方法。

0x03_特殊情况:注入空值和特殊符号

在给属性赋值的时候,如果是引用数据类型,就可以赋null值,但是如果想在DI中对象实现赋null值,发现报错

SpringIOC第3弹-XML实现DI
image-20221026215327182

因为底层是用Integet.parseInt对null进行转换的,所以不可以。

此时如果说想要显式地赋null值,可以这么写:

<bean id="user2" class="com.bones.bean.User">
<property name="userid" >
<null></null>
</property>
</bean>

还有就是特殊符号比如<,>,&等,在xml文件中这些特殊符号会有特殊的意义,所以不能直接作为值赋值。

SpringIOC第3弹-XML实现DI

此时有两种解决办法:

1.字符实体:

SpringIOC第3弹-XML实现DI
image-20221026215804405

比如上面的&可以用&amp;代替:

SpringIOC第3弹-XML实现DI

2. <![CDATA[内容]]>

<bean id="user2" class="com.bones.bean.User">
<property name="userid" >
<null></null>
</property>
<property name="username">
<value> <![CDATA[&123456]]></value>
</property>
</bean>

0x04_Bean的引用

下面介绍几种bean引用的写法

准备2个类:Baby,Mother

package com.bones.bean;

import Java.util.Date;

/**
* @author : bones
* @version : 1.0
*/

public class Baby {
private String bname;
private Date birthDate;

public Baby(String bname, Date birthDate) {
this.bname = bname;
this.birthDate = birthDate;
}

public Baby() {
}

public String getBname() {
return bname;
}

public void setBname(String bname) {
this.bname = bname;
}

public Date getBirthDate() {
return birthDate;
}

public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}

@Override
public String toString() {
return "Baby{" +
"bname='" + bname + ''' +
", birthDate=" + birthDate +
'}';
}
}


package com.bones.bean;

/**
* @author : bones
* @version : 1.0
*/

public class Mother {
private String mname;
private Baby baby;

public Mother(String mname, Baby baby) {
this.mname = mname;
this.baby = baby;
}

public Mother() {
}

public String getMname() {
return mname;
}

public void setMname(String mname) {
this.mname = mname;
}

public Baby getBaby() {
return baby;
}

public void setBaby(Baby baby) {
this.baby = baby;
}

@Override
public String toString() {
return "Mother{" +
"mname='" + mname + ''' +
", baby=" + baby +
'}';
}
}

写法1:外部引用

<bean id="date" class="java.util.Date"/>

<bean id="baby1" class="com.bones.bean.Baby">
<property name="bname" value="baby1"/>
<property name="birthDate" ref="date"/>
</bean>

写法2:内部引用

<!--    内部引用-->
<bean id="baby2" class="com.bones.bean.Baby">
<property name="bname" value="baby2"/>
<property name="birthDate" >
<bean class="java.util.Date"/>
</property>
</bean>

如果Mother类想要引用Baby类,可以这么写:(这时候需要实现多层的引用)

<!--    内部多层引用-->
<bean id="mother1" class="com.bones.bean.Mother">
<property name="mname" value="mother1"/>
<property name="baby">
<bean class="com.bones.bean.Baby">
<property name="bname" value="baby3"/>
<property name="birthDate">
<bean class="java.util.Date"/>
</property>
</bean>
</property>
</bean>

写法3:级联引用bean

<!--    级联引用-->
<bean id="baby4" class="com.bones.bean.Baby"/>
<bean id="mother2" class="com.bones.bean.Mother">
<property name="mname" value="mother2"/>
<property name="baby" ref="baby4"/>
<property name="baby.bname" value="baby4"/>
<property name="baby.birthDate" >
<bean class="java.util.Date"/>
</property>
</bean>

上面几种写法,实际中用的频率由上到下越来越低,但是作为学习,都要了解。

0x05_集合注入

首先准备实体类,属性中包含各种常见的集合。

package com.bones.bean;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author : bones
* @version : 1.0
*/

public class Person {
private List<String> bookNameList;
private Set<String> bookSet;
private String[] bookArray;
private Map<String,String> bookMap;
private List<Book> bookList;

public Person(List<String> bookNameList, Set<String> bookSet, String[] bookArray, Map<String, String> bookMap, List<Book> bookList) {
this.bookNameList = bookNameList;
this.bookSet = bookSet;
this.bookArray = bookArray;
this.bookMap = bookMap;
this.bookList = bookList;
}

public Person() {
}

public List<String> getBookNameList() {
return bookNameList;
}

public void setBookNameList(List<String> bookNameList) {
this.bookNameList = bookNameList;
}

public Set<String> getBookSet() {
return bookSet;
}

public void setBookSet(Set<String> bookSet) {
this.bookSet = bookSet;
}

public String[] getBookArray() {
return bookArray;
}

public void setBookArray(String[] bookArray) {
this.bookArray = bookArray;
}

public Map<String, String> getBookMap() {
return bookMap;
}

public void setBookMap(Map<String, String> bookMap) {
this.bookMap = bookMap;
}

public List<Book> getBookList() {
return bookList;
}

public void setBookList(List<Book> bookList) {
this.bookList = bookList;
}

@Override
public String toString() {
return "Person{" +
"bookNameList=" + bookNameList +
", bookSet=" + bookSet +
", bookArray=" + Arrays.toString(bookArray) +
", bookMap=" + bookMap +
", bookList=" + bookList +
'}';
}
}

其中的Book实体类:

package com.bones.bean;

/**
* @author : bones
* @version : 1.0
*/

public class Book {
private String bookName;
private String bookAuthor;

public Book(String bookName, String bookAuthor) {
this.bookName = bookName;
this.bookAuthor = bookAuthor;
}

public Book() {
}

public String getBookName() {
return bookName;
}

public void setBookName(String bookName) {
this.bookName = bookName;
}

public String getBookAuthor() {
return bookAuthor;
}

public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}

@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + ''' +
", bookAuthor='" + bookAuthor + ''' +
'}';
}
}

applicationContext4.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:c="http://www.springframework.org/schema/c"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
"
>


<util:list id="outerBookList">
<bean id="book1" class="com.bones.bean.Book" c:bookName="Effective Java" c:bookAuthor="Bloch"/>
<bean id="book2" class="com.bones.bean.Book" c:bookName="Spring技术内幕" c:bookAuthor="计文柯"/>
<bean id="book3" class="com.bones.bean.Book" c:bookName="Mybatis技术内幕" c:bookAuthor="徐郡明"/>
</util:list>

<bean id="person1" class="com.bones.bean.Person">
<property name="bookNameList">
<list>
<value>Effective Java</value>
<value>Spring技术内幕</value>
<value>Mybatis技术内幕</value>
</list>
</property>
<property name="bookArray">
<array>
<value>Effective Java</value>
<value>Spring技术内幕</value>
<value>Mybatis技术内幕</value>
</array>
</property>
<property name="bookSet">
<set>
<value>Effective Java</value>
<value>Spring技术内幕</value>
<value>Mybatis技术内幕</value>
</set>
</property>
<property name="bookMap">
<map>
<entry key="Effective java" value="Bloch"/>
<entry key="Spring技术内幕" value="计文柯"/>
<entry key="Mybatis技术内幕" value="徐郡明"/>
</map>
</property>
<property name="bookList" ref="outerBookList">
</property>
</bean>



</beans>

测试方法:

package com.bones.test01;

import com.bones.bean.Baby;
import com.bones.bean.Mother;
import com.bones.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;

/**
* @author : bones
* @version : 1.0
*/

public class TestDI_BeanCollectionRef {
@Test
public void testBeanTag(){
//获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext4.xml");
Person person1 = applicationContext.getBean("person1", Person.class);
System.out.println("person1.getBookNameList() = " + person1.getBookNameList());
System.out.println("person1.getBookArray() = " + Arrays.toString(person1.getBookArray()));
System.out.println("person1.getBookList() = " + person1.getBookList());
System.out.println("person1.getBookMap() = " + person1.getBookMap());
System.out.println("person1.getBookSet() = " + person1.getBookSet());

}
}

测试结果:

SpringIOC第3弹-XML实现DI
image-20221027135133299

总结:

【1】util可以定义公共集合,要加上约束:

SpringIOC第3弹-XML实现DI
image-20221027135454230
xmlns:util="http://www.springframework.org/schema/util"

http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd

定义公共集合:

<util:list id="outerBookList">
<bean id="book1" class="com.bones.bean.Book" c:bookName="Effective Java" c:bookAuthor="Bloch"/>
<bean id="book2" class="com.bones.bean.Book" c:bookName="Spring技术内幕" c:bookAuthor="计文柯"/>
<bean id="book3" class="com.bones.bean.Book" c:bookName="Mybatis技术内幕" c:bookAuthor="徐郡明"/>
</util:list>

【2】不同的Collection集合注入用标签即可:

SpringIOC第3弹-XML实现DI


原文始发于微信公众号(小东方不败):SpringIOC第3弹-XML实现DI

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/47085.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!