Spring教程06-XML装配Bean

阅读原文
XML装配Bean的方式是Spring最初描述配置的主要方式,当然就现在还是有很多人以此方式来装配Bean,下面我们就来探讨以XML的形式装配Bean,来看看Spring配置文件的强大!

1、XML装配Bean

1.1、创建Spring配置文件规范

由于我使用的是IDEA编译器,那我就简单说一下IDEA是如何创建Spring配置文件的,来看截图:
在这里插入图片描述
Spring配置文件规范:

<?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">
</beans>

其实也很容易理解,这段配置跟JavaConfig中@Configuration起类似的效果。

1.2、声明一个简单的Bean

在XML中我们需要使用标签来声明一个Bean,就好比我们在JavaConfig中使用@Bean来声明Bean是一样的。

<!-- 声明Blog这个Bean-->
<bean class="com.icypt.learn.service.Blog"/>

默认情况下这个Bean的ID是com.icypt.learn.service.Blog#0,“#0”是一种计数方式,用来区别同一类的不同实例。但是这个ID在我们后续引用中会显得特别冗长、不太方便,为了使我们的代码具有可读性,我们使用标签的id属性指定Bean的ID:

<bean id="blog" class="com.icypt.learn.service.Blog"/>

至此我们一个简单的Bean声明完成,下面做个简单的测试。

编写测试代码

public class Blog {
    public void sayHello() {
        System.out.println("***************hello world!****************");
    }
}
public class User {
    public void getUser() {
        System.out.println("*********我是icypt************");
    }
}
public class TestXmlConfigBean {
private static ClassPathXmlApplicationContext acac = new 
ClassPathXmlApplicationContext("application.xml");
    public static void main(String[] args) {
        Blog blog = acac.getBean("blog", Blog.class);
        blog.sayHello();
    }
}

运行测试结果

18:16:06,315 DEBUG main xml.XmlBeanDefinitionReader:395 - Loaded 1 bean definitions from class path resource [application.xml]
18:16:06,388 DEBUG main support.DefaultListableBeanFactory:213 - Creating shared instance of singleton bean 'blog'
***************hello world!****************

通过测试结果可以发现,我们已经成功的使用XML配置完成了一个简单Bean的装配。

1.3、使用XML配置进行依赖注入

1.3.1、使用构造器注入

1、注入Bean对象
修改Blog类让它依赖User类:

public class Blog {
    private User user;
    public Blog(User user) {
        this.user = user;
    }
    public void sayHello() {
        System.out.println("***************hello world!****************");
    }
}

注入配置:

<bean id="user" class="com.icypt.learn.service.User"/>
<bean id="blog" class="com.icypt.learn.service.Blog">
	<!-- 构造注入user-->
	<constructor-arg ref="user"/>
</bean>

<constructor-arg ref="user"/>:将User的应用传递到Blog的构造器中完成注入。
对于以上的注入方式,我们也可采用Spring的c命名空间更加简洁的完成配置:

<bean id="blog" class="com.icypt.learn.service.Blog" c:user-ref="user"/>

c:user-ref="user":其中c表示命名空间,user表示构造参数名称,-ref和传统的配置一样,表示传递的引用ID。
其实我们还可以通过构造参数索引定位参数的位置:

<!-- 普通构造注入依赖构造参数索引位置-->
<bean id="blog" class="com.icypt.learn.service.Blog">
	<!-- 构造注入user-->
	<constructor-arg index="0" ref="user"/>
</bean>

Index:表示的是构造参数的索引从0开始。

<bean id="blog" class="com.icypt.learn.service.Blog" c:_0-ref="user"/>

c:_0-ref:_0表示的是构造参数的索引从0开始。

2、注入基本数据类型
修改Blog类:

public class Blog {
    private User user;
    private String blogName;
    private String blogTitle;
    private Integer blogSort;
    private List<String> blogTags;
    public Blog(String blogName, String blogTitle, Integer blogSort, List<String> blogTags) {
        this.blogName = blogName;
        this.blogTitle = blogTitle;
        this.blogSort = blogSort;
        this.blogTags = blogTags;
    }
    public Blog(User user) {
        this.user = user;
    }
    public Blog() {
        
    }
    public void sayHello() {
        System.out.println("***************hello world!****************");
    }
    public void printBlogTags() {
        for(String tag : this.blogTags) {
            System.out.println("**********" + tag);
        }
    }
}

修改测试类:

@Test
public void testPrintTags() {
	Blog blog = acac.getBean("blog", Blog.class);
	blog.printBlogTags();
}

运行测试方法

21:10:15,682 DEBUG main xml.XmlBeanDefinitionReader:395 - Loaded 2 bean definitions from class path resource [application.xml]
21:10:15,767 DEBUG main support.DefaultListableBeanFactory:213 - Creating shared instance of singleton bean 'user'
21:10:15,802 DEBUG main support.DefaultListableBeanFactory:213 - Creating shared instance of singleton bean 'blog'
**********java
**********spring
**********springboot

根据运行结果可知,我们已成功注入基本数据类型。
普通构造写法和c标签写法混合使用:

<bean id="blog" class="com.icypt.learn.service.Blog" c:blogName="SpringBoot" c:_1="first boot">
	<constructor-arg index="2">
		<null/>
	</constructor-arg>
	<constructor-arg index="3">
		<list>
			<value>java</value>
			<value>spring</value>
			<value>springboot</value>
		</list>
	</constructor-arg>
</bean>

<null/>:表示传入一个null值。
注入set集合和list 类似这里就不做演示了,需要注意的是,set中value的值如果是重复的则会被覆盖,且注入的set集合顺序是无序的。

1.3.2、使用setter方法注入

新建Movie类:

public class Movie  {
    private String movieName;
    private String movieDesc;
    private Double price;
    private User user;
    private List<String> movieTags;
    public void setMovieName(String movieName) {
        this.movieName = movieName;
    }
    public void setMovieDesc(String movieDesc) {
        this.movieDesc = movieDesc;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public void setMovieTags(List<String> movieTags) {
        this.movieTags = movieTags;
    }
    public void printMovieInfo() {
        System.out.println("********电影名称************" + this.movieName);
        System.out.println("********电影描述************" + this.movieDesc);
        System.out.println("********电影价格************" + this.price + "元");
        String tags = "";
        for(String str : movieTags) {
            tags += str + ",";
        }
        System.out.println("********电影标签************{" + tags.substring(0, tags.lastIndexOf(",")) +"}");
    }
}

修改配置文件:

<bean id="movie" class="com.icypt.learn.service.Movie">
	<property name="movieName" value="战狼"/>
	<property name="movieDesc" value="比较好看的军事题材电影"/>
	<property name="price" value="35.00"/>
	<property name="movieTags">
		<list>
			<value>军事</value>
			<value>特种兵</value>
			<value>坦克漂移</value>
		</list>
	</property>
</bean>

<property>标签是依赖setter方法注入的,所以Movie类中必须要有对应属性的setter方法。

运行结果如下:

21:48:30,911 DEBUG main xml.XmlBeanDefinitionReader:395 - Loaded 2 bean definitions from class path resource [application.xml]
21:48:30,982 DEBUG main support.DefaultListableBeanFactory:213 - Creating shared instance of singleton bean 'user'
21:48:31,023 DEBUG main support.DefaultListableBeanFactory:213 - Creating shared instance of singleton bean 'movie'
********电影名称************战狼
********电影描述************比较好看的军事题材电影
********电影价格************35.0********电影标签************{军事,特种兵,坦克漂移}
通过运行结果可以发现,我们已经成功的通过setter完成了基本数据类型的注入。
与构造方法注入类似setter方法注入spring也提供了一种p命名空间,下面来看p标签的使用。
<bean id="movie" class="com.icypt.learn.service.Movie"
	  p:movieName="战狼"
	  p:price="35.00"
	  p:user-ref="user"
	  p:movieDesc="比较好看的军事题材电影">
	<property name="movieTags">
		<list>
			<value>军事</value>
			<value>特种兵</value>
			<value>坦克漂移</value>
		</list>
	</property>
</bean>

看起来p标签的写法更为优雅一些,实际开发中还是要根据个人习惯选择。
通过构造器和setter方法的注入我们发现如果使用命名空间的方式注入时,对于集合数据类型我们还是采用普通的方式注入,那么下面我们引出Spring的另一个命名空间util。
修改之前配置:

<!-- 使用util命名空间定义Map集合 -->
<util:list id="movieTags">
	<value>军事</value>
	<value>特种兵</value>
	<value>坦克漂移</value>
</util:list>
<!-- 使用p命名空间setter方法注入 -->
<bean id="movie" class="com.icypt.learn.service.Movie"
	  p:movieName="战狼"
	  p:price="35.00"
	  p:user-ref="user"
	  p:movieDesc="比较好看的军事题材电影"
	  p:movieTags-ref="movieTags">
</bean>

这样以来是不是我们的配置显得更加简洁与优雅,那么对于util命名空间的支持,spirng总共提供了五种标签元素:
<util:constant>:定义静态常量;
<util:list>:定义list集合;
<util:map>:定义map集合;
<util:set>:定义set集合;
<util:properties>:定义properties集合;
<util:property-path>:取得bean某一属性的值;
如何使用这里就不做演示了,因为比较简单且使用方式都很类似,大家有时间可以去看一下官方文档搜索“the util schema”就可以找到所有有关util命名空间的使用方式了。

更多最新技术文章,请关注“冰点IT”公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值