05 Spring框架 依赖注入(二)
上一节我们讲了三种信息的注入,满足一个类的属性信息的注入,但是如果我们需要向一个实例中注入另一个实例呢?就像我们创建一个学生类,里边有:姓名,性别,年龄,成绩等几个属性(我习惯把类的域叫做属性),但是成绩可以是一个类,可以用这个类创建一个成绩域,即成绩里面有:语文,数学,英语......等几个属性。(上一节我们已经做了一个实验)
Spring中信息的注入也是这样,可以注入各种信息,接下来我们来罗列一下这几个注入方法。
各种类型信息的注入:
- 注入字符串,单个数值。
- 注入bean对象
- 注入集合Array,list,set,Map,properties
- 注入外部信息
- 注入Spring表达式
- byName注入和byType注入
- 抽象bean
前面我们已经说的就是字符串和单个数值的注入和注入bean对象,接下来我们说一下其他的几种注入方式。
<!--set注入 其他bean(上一节已经有例子) -->
<bean id="c4" class="com.Spring.Demo.Student">
<property name="c" ref="c2"></property>
<property name="p" ref="c3"></property>
</bean>
这里的ref指的是其他实例的id
这样就可以将其他实例注入当前的bean中。
注入list,map,set,properties,就像注入字符串和单个数值那样,只是这里注入的是一组集合而已。
<bean id="c5" class="com.Spring.Demo.MessageBean">
<property name="name" value="Tom"></property>
<property name="age" value="18"></property>
<property name="birth" value="2000-10-1"></property>
<!--信息的外部注入 friends在下边会给出 -->
<property name="friends" ref="friends"></property>
<!-- set的信息注入 /和list/Array的方法相同-->
<property name="cities">
<set>
<value>上海</value>
<value>北京</value>
</set>
</property>
<!-- Map的注入方式 -->
<property name="books">
<map>
<entry key="10001" value="java基础"></entry>
<entry key="10002" value="javaWeb开发"></entry>
</map>
</property>
<!-- properties的注入方式 -->
<property name="db">
<props>
<prop key="dbname">root</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
Spring表达式(SPEL)的注入(注入其他bean的值):
<bean id="" class="">
<!--map的表达式-->
<property name="" value="#{id名字.key}"></property>
<!--若是属性,对应的实体类应该有getter方法。-->
<property name="" value="#{id名字.属性}"></property>
<!--如果引用的是一个list,可以使用方括号进行选取值-->
<property name="" value="#{id名字.SomeList.[0]}">
</property>
<!--产生0-1的随机数-->
<property name="" value="#{T(java.lang.Math).random()}"></property>
<!--调用方法-->
<property name="" value="#{id名字.方法名(此方法要有返回值)}"></property>
<!--Spring EL 很强大(不太常用),这里就不一一列举了-->
</bean>
外部信息注入
可以单独将集合拿出来,如需使用直接调用。
<!--list的表达式:信息的外部注入,经常用到的值放在这里,方便引用-->
<util:list id="friends">
<value>Tom</value>
<value>Jack</value>
</util:list>
我么来测试一下:
这个是实体类:
package com.Spring.Demo;
import java.sql.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class MessageBean {
private String name;
private String age;
private Date birth;
private List<String> friends;
private Set<String> cities;
private Map<String,String> books;
private Properties db;
public void show(){
System.out.println("name:"+name);
System.out.println("age:"+age);
System.out.println("birth:"+birth);
for(String s:friends){
System.out.println("list集合:"+s);
}
for(String c:cities){
System.out.println(c);
}
System.out.println("Map的使用输出!");
Set<Entry<String,String>>booksSet=books.entrySet();
for(Entry<String, String> e:booksSet){
System.out.println(e.getKey() +e.getValue());
}
System.out.println("properties的使用");
Set<Object> keys=db.keySet();
for(Object key:keys){
System.out.println(key+":"+db.getProperty(key.toString()));
}
}
public void setDb(Properties db) {
this.db = db;
}
public void setBooks(Map<String, String> books) {
this.books = books;
}
public void setCities(Set<String> cities) {
this.cities = cities;
}
public void setBirth(String birth) {
Date date=Date.valueOf(birth);
this.birth = date;
}
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
public void setFriends(List<String> friends) {
this.friends = friends;
}
}
package com.Spring.Demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMessageBean {
public static void main(String[]args){
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
MessageBean c5=(MessageBean)ac.getBean("c5");
c5.show();
}
}
name:Tom
age:18
birth:2000-10-01
list集合:Tom
list集合:Jack
上海
北京
Map的使用输出!
byName方式的域属性自动注入
在再章节04里面我们说过域属性为引用类型的时候使用ref进行注入,这一节我们通过bean标签内的autowire属性进行byName方式的域属性自动注入,示例如下:
<bean id = "book" class = "com.di.ByName.Book" autowire="byName"><!--这里使用byName-->
<property name = "bname" value = "Java技术"></property>
<property name = "bnumber" value ="201410185732" ></property>
</bean>
<!--这里的id要和book里面的属性命名相同-->
<bean id = "bpub" class="com.di.ByName.publisher">
<property name="name" value="清华大学出版社"></property>
<property name="address" value="xxxx"></property>
</bean>
public class Book {
private String bname;
private String bnumber;
private publisher bpub;
//省略了setter和toString方法
}
public class publisher {
String name;
String address;
//省略了setter和toString方法
}
//测试类(Junit)
public class test {
@Test
public void Test01() {
String resource = "com/di/ByName/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
Book book = (Book)ac.getBean("book");
System.out.println(book);
}
}
//控制台输出
Book [bname=Java技术, bnumber=201410185732, bpub=publisher [name=清华大学出版社, address=xxxx]]
这样配置过后,程序运行起来,容器就会帮助我们将域属性名作为id到它内部找名称相同的bean进行注入。
byType方式的域属性自动注入:
byType方式的自动注入和byName基本相同,唯一不同点是:
当我们有一个类继承publisher的时候,恰好我们配置文件中也注册了这个bean,这个时候如果autowire属性为byType时,就能够注入这个继承publisher类子类的bean(向上转型)。但是同一个配置文件中不能够同时注册相同类型的bean,否则不唯一,容器不知道我们注入的是哪一个,自然而然也就会报错了。
这种情况下(使用byType),我们可以将它注入的bean的id删除,即匿名bean,因为我们是通过扫描类型来完后注入的,不需要id。
还有一种,可以将匿名bean直接放入需要注入的property中:
这个内部匿名bean就只能由myStudent来使用。
同类抽象bean
就像java里面的抽象类一样,我们注册bean的时候还可以命名抽象bean,用来防止信息的冗余。
<bean id="baseStudent"
<!--abstract="true",使得不能够在程序中通过getBean获取-->
class="com.di.AbstractBean.Student" abstract="true">
<property name="school" value="哈佛大学"></property>
<property name="grade" value="3"></property>
</bean>
<!--parent="baseStudent" 继承指定的bean-->
<bean id="student1"
class="com.di.AbstractBean.Student" parent="baseStudent">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="student2" class="com.di.AbstractBean.Student" parent="baseStudent" >
<property name="id" value="2"></property>
<property name="name" value="李四"></property>
</bean>
<bean id="student3" class="com.di.AbstractBean.Student" parent="baseStudent">
<property name="id" value="3"></property>
<property name="name" value="王五"></property>
</bean>
(上面省略了其他代码)这样就减轻了我们配置时候的负担。
异类抽象bean
和我们同类抽象bean相同,继承base bean的bean可以是不同的类注册的bean(但是它们有相同的部分),这样也能够进行继承。
<bean id="base" abstract="true">
<property name="school" value="哈佛大学"></property>
</bean>
<bean id="student"
class="com.di.AbstractBean.Student" parent="base">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="teacher" class="com.di.AbstractBean.Teacher" parent="base" >
<property name="id" value="2"></property>
<property name="name" value="李四"></property>
</bean>
05 Spring框架 依赖注入(二)的更多相关文章
- SpringBoot系列: 理解 Spring 的依赖注入(二)
==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @B ...
- 04 Spring框架 依赖注入(一)
整理了一下之前学习spring框架时候的一点笔记.如有错误欢迎指正,不喜勿喷. 上一节我们讲了几个bean的一些属性,用来限制我们实例创建过后的状态. 但是细心的我们会发现其实上面demo创建的实例并 ...
- spring框架——依赖注入
依赖注入:DI 又称控制反转:IoC 项目名字spring_DI 一.implement包中定义了两个接口Food和Person 1.接口Food package org.interfaces; pu ...
- 07 Spring框架 依赖注入(四)基于注解的依赖注入
前面几节我们都在使用xml进行依赖的注入,但是在实际的开发中我们往往偏爱于使用注解进行依赖注入,因为这样更符合我们人的思维,并且更加快捷,本节就来讲述Spring基于注解的依赖注入: 信息注入注解 @ ...
- 06 Spring框架 依赖注入(三)多配置文件
在Spring前几节的学习中我们都使用了一个配置文件,就像struts2中可以包含其他的配置文件,我们能不能使用多个配置文件呢(在工程比庞大,配置比较多的时候)? Spring多配置文件分为两种: 平 ...
- Spring.NET依赖注入框架学习--简单对象注入
Spring.NET依赖注入框架学习--简单对象注入 在前面的俩篇中讲解了依赖注入的概念以及Spring.NET框架的核心模块介绍,今天就要看看怎么来使用Spring.NET实现一个简单的对象注入 常 ...
- Spring.NET依赖注入框架学习--实例化容器常用方法
Spring.NET依赖注入框架学习---实例化容器常用方法 本篇学习实例化Spring.NET容器的俩种方式 1.通过XmlObjectFactory创建一个Spring.NET容器 IResour ...
- Spring.NET依赖注入框架学习--简介
Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...
- Spring.NET依赖注入框架学习--入门
Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...
随机推荐
- CentOS sendmail安装及邮件域名配置
http://www.centoscn.com/CentosServer/lighttpd/2013/0726/650.html sendmail是Linux下优秀的邮件系统.在不做任何设定的情况下, ...
- 关于UITableView界面刷新
在TableView中的数据发生改变的时候,往往会发现UITableView中的数据没有更新,通常需要滚动后才会更新. 这个是因为他的重绘机制的问题. 一般情况下可以用下面这个方法解决: 在viewW ...
- sqrt函数实现(神奇的算法)
我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然 ...
- 各种排序算法C++
各种排序算法 插入排序 直接插入排序 void InsertSort(int arr[], int len) { int i, j; int temp; for (i = 1; i < len; ...
- Java基础10 接口的继承与抽象类(转载)
接口继承 接口继承(inheritance)与类继承很类似,就是以被继承的interface为基础,增添新增的接口方法原型.比如,我们以Cup作为原interface: interface Cup{ ...
- xilinx 赛灵思fpga verilog hdl 教程
http://www.eefocus.com/article/08-03/37231s.html http://wenku.baidu.com/link?url=5mdkMmm4BGGi7gRdgSk ...
- Java凝视分类
Java凝视分类 1.单行凝视 //打印结果 System.out.println("结果是:"+result); 2.多行凝视 /** * @autho ...
- 我买网B轮融资成功,五周年豪掷千万回馈会员
对中粮我买网而言,近期的B轮融资应该算是最大的好消息了------8月1日,中粮我买网在京宣布完毕B轮融资.金额高达1亿美元.被称为"食品电商史上最大融资".据悉,本次融资 ...
- KMP hihoCoder1015 KMP算法
人太蠢,,看了一天的KMP.. 刚開始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并非Next数组! 总认为和之前看过的全然不一样.. . 后来又百度了一下KMP,研究了非常久,然后用自己的逻 ...
- 在NodeJS中使用流程控制工具Async
本文介绍一款流程控制工具async,在编写接口或者编写测试用例的过程中总是会用到它. 由于nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦.Async的流程控制就是为了 ...