`

跟我学Spring3 学习笔记五 注入

    博客分类:
  • java
 
阅读更多

跟我学Spring3 学习笔记一

跟我学Spring3 学习笔记二

跟我学Spring3 学习笔记三

跟我学Spring3 学习笔记四

 

 

常量注入:

 

<!-- 常量注入 -->
	<bean id="AfxMessage" class="java.lang.String">
		<constructor-arg index="0" value="Hello Spring by id" />
	</bean>
	<bean id="beanSetAfx" class="com.constructor.HelloImplConstr">
		<property name="message">
			<idref bean="AfxMessage" /> 
		</property>
		<property name="index" value="5" />
	</bean>
 

 

 

//setter注入 +常量注入  根据set get 函数进行注入
HelloApi helloApi5 = context.getBean("beanSetAfx",HelloApi.class);
helloApi5.sayHello();

 

 

/**
 * 构造器注入可以根据参数索引注入、参数类型注入或Spring3支持的参数名注入,
 * 但参数名注入是有限制的,需要使用在编译程序时打开调试模式
 * (即在编译时使用“javac –g:vars”在class文件中生成变量调试信息,默认是不包含变量调试信息的,
 * 从而能获取参数名字,否则获取不到参数名字)
 * 或在构造器上使用@ConstructorProperties(java.beans.ConstructorProperties)注解来指定参数名。
 */
public class HelloImplConstr implements HelloApi {

	private String message;
	private int index;
	
	public HelloImplConstr(){
		
	}
	@ConstructorProperties({"message","index"})
	public HelloImplConstr(String message,int index){
		this.message = message;
		this.index = index;
	}
	public void sayHello() {
		System.out.println(this.index+":"+this.message);

	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public int getIndex() {
		return index;
	}
	public void setIndex(int index) {
		this.index = index;
	}
}
 

第一种方式可以在容器初始化时校验被引用的Bean是否存在,如果不存在将抛出异常,
而第二种方式只有在Bean实际使用时才能发现传入的Bean的ID是否正确,
可能发生不可预料的错误。因此如果想注入Bean的ID,推荐使用第一种方式。

将在容器初始化时校验注入的ID对于的Bean是否存在,如果不存在将抛出异常。
将在XML解析时校验注入的ID对于的Bean在当前配置文件中是否存在,
如果不存在将抛出异常,它不同于是校验发生在XML解析式而非容器初始化时,
且只检查当前配置文件中是否存在相应的Bean。

 

 

集合注入:

 

<!-- list set 注入集合-->
	<bean id="listBean" class="com.dilist.HelloDiList">
		<property name="valuesList">
			<!-- <list value-type="java.lang.String" merge="default"> -->
			<list><!-- <set> -->
				<value>1</value>
				<value>2</value>
				<value>3</value>
			</list>
		</property>
	</bean>
	<!-- Collection类型:因为Collection类型是Set和List类型的基类型,
			所以使用<set>或<list>标签都可以进行注入,配置方式完全和以上配置方式一样,
			只是将测试类属性改成“Collection”类型,
	 -->
	
	<!-- 注入数组类型 -->
	<bean id="arrayBean" class="com.dilist.HelloDiList">
		<property name="array">
			<array value-type="java.lang.String" merge="default">
				<value>1</value>
				<value>2</value>
			</array>
		</property>
		
		<property name="array2">
			<array>
				<array>
					<value>1</value>
					<value>2</value>
				</array>
				<array>
					<value>4</value>
					<value>5</value>
				</array>
			</array>
		</property>
		
	</bean>

 

public class HelloDiList implements HelloApi,HelloApiArry{

	private String array[];
	private String array2[][];
	
	private List<String> valuesList;
	
	public void sayHello() {
		for (int i = 0; i < valuesList.size(); i++) {
			System.out.println(valuesList.get(i));
		}
		
	}
	
	public void sayHelloArray(){
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
		
		for (int i = 0; i < array2.length; i++) {
			for (int j = 0; j < array2[i].length; j++) {
				System.out.println(array2[i][j]);
			}
		}
	}

	public List<String> getValuesList() {
		return valuesList;
	}

	public void setValuesList(List<String> valuesList) {
		this.valuesList = valuesList;
	}

	public String[] getArray() {
		return array;
	}

	public void setArray(String[] array) {
		this.array = array;
	}

	public String[][] getArray2() {
		return array2;
	}

	public void setArray2(String[][] array2) {
		this.array2 = array2;
	}

}
 

 

调用处:

 

//读取配置文件实例化一个Ioc容器
ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
		
//setter注入 +list set常量 注入集合、数组和字典
HelloApi helloApi = context.getBean("listBean",HelloApi.class);
helloApi.sayHello();
		
//setter注入 +数组 一维 二维 常量 注入集合、数组和字典
HelloApiArry helloApi2 = context.getBean("arrayBean",HelloApiArry.class);
helloApi2.sayHelloArray();
 

 

 

Map注入

 

/**
 * 注入字典(Map)类型:字典类型是包含键值对数据的数据结构,需要使用<map>标签来配置注入,
 * 其属性“key-type”和“value-type”分别指定“键”和“值”的数据类型,其含义和<list>标签的“value-type”含义一样,
 * 在此就不罗嗦了,并使用<key>子标签来指定键数据,<value>子标签来指定键对应的值数据
 */
public class HelloDiMap implements HelloApi {

	private Map<String, String> mapValues;

	public void sayHello() {
		for (String key : mapValues.keySet()) {
			System.out.println(key+":"+mapValues.get(key));
		}
	}

	public Map<String, String> getMapValues() {
		return mapValues;
	}

	public void setMapValues(Map<String, String> mapValues) {
		this.mapValues = mapValues;
	}

}
 

两种配置方法

 

<!-- 注入map类型 -->
	<bean id="mapBean" class="com.dilist.HelloDiMap">
		<property name="mapValues">
			<map key-type="java.lang.String"
				value-type="java.lang.String">
				<entry>
					<key>
						<value>1</value>
					</key>
					<value>11</value>
				</entry>
				<entry key="2" value="22" />
			</map>
		</property>
	</bean>
 

 

Properties 注入:

 

/**
 * Properties注入:Spring能注入java.util.Properties类型数据,需要使用<props>标签来配置注入,
 * 键和值类型必须是String,不能变,子标签<prop key=”键”>值</prop>来指定键值对
 */
public class HelloDiProperties implements HelloApi {

	private Properties properties;

	private Properties properties2;
	
	public void sayHello() {
		for(Object key :properties.keySet()){
			System.out.println(key+":"+properties.getProperty((String)key));
		}
		
		for(Object key :properties2.keySet()){
			System.out.println(key+":"+properties2.getProperty((String)key));
		}
	}

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	public Properties getProperties2() {
		return properties2;
	}

	public void setProperties2(Properties properties2) {
		this.properties2 = properties2;
	}

}

 properties XML配置注入

 

<!-- 注入properties类型 -->
	<bean id="properBean" class="com.dilist.HelloDiProperties">
		<property name="properties">
			<props value-type="int" merge="default"><!-- 虽然指定value-type,但是不起作用 -->
				<prop key="1">1sss</prop>           <!-- Properties 建和值都是String类型 -->
				<prop key="2">2</prop>
			</props>
		</property>
		<property name="properties2">
			<value> <!-- 分隔符可以是 “换行”、“;”、“,” 不建议该方式,优先选择第一种方式 -->
				1=11
				2=22;<!-- 这样的分隔符好像没用 -->
			    3=33,
				4=44
			</value>
		</property>
		
	</bean>

 

 

引用其它Bean

一、构造器注入方式:

(1)通过” <constructor-arg>”标签的ref属性来引用其他Bean

(2)通过” <constructor-arg>”标签的子<ref>标签来引用其他Bean,使用bean属性来指定引用的Bean

二、setter注入方式:

(1)通过” <property>”标签的ref属性来引用其他Bean

(2)通过” <property>”标签的子<ref>标签来引用其他Bean,使用bean属性来指定引用的Bean

 

 

 

 

为什么要应用依赖注入,应用依赖注入能给我们带来哪些好处呢?

     动态替换Bean依赖对象,程序更灵活:替换Bean依赖对象,无需修改源文件:应用依赖注入后,由于可以采用配置文件方式实现,从而能随时动态的替换Bean的依赖对象,无需修改java源文件;

     更好实践面向接口编程,代码更清晰:在Bean中只需指定依赖对象的接口,接口定义依赖对象完成的功能,通过容器注入依赖实现;

     更好实践优先使用对象组合,而不是类继承:因为IoC容器采用注入依赖,也就是组合对象,从而更好的实践对象组合。

  • 采用对象组合,Bean的功能可能由几个依赖Bean的功能组合而成,其Bean本身可能只提供少许功能或根本无任何功能,全部委托给依赖Bean,对象组合具有动态性,能更方便的替换掉依赖Bean,从而改变Bean功能;
  • 而如果采用类继承,Bean没有依赖Bean,而是采用继承方式添加新功能,,而且功能是在编译时就确定了,不具有动态性,而且采用类继承导致Bean与子Bean之间高度耦合,难以复用。

     增加Bean可复用性:依赖于对象组合,Bean更可复用且复用更简单;

     降低Bean之间耦合:由于我们完全采用面向接口编程,在代码中没有直接引用Bean依赖实现,全部引用接口,而且不会出现显示的创建依赖对象代码,而且这些依赖是由容器来注入,很容易替换依赖实现类,从而降低Bean与依赖之间耦合;

     代码结构更清晰:要应用依赖注入,代码结构要按照规约方式进行书写,从而更好的应用一些最佳实践,因此代码结构更清晰。

 

从以上我们可以看出,其实依赖注入只是一种装配对象的手段,设计的类结构才是基础,如果设计的类结构不支持依赖注入,Spring IoC容器也注入不了任何东西,从而从根本上说“如何设计好类结构才是关键,依赖注入只是一种装配对象手段”。

前边IoC一章我们已经了解了Bean依赖容器,那容器如何注入Bean的依赖资源,Spring IoC容器注入依赖资源主要有以下两种基本实现方式:

     构造器注入:就是容器实例化Bean时注入那些依赖,通过在在Bean定义中指定构造器参数进行注入依赖,包括实例工厂方法参数注入依赖,但静态工厂方法参数不允许注入依赖;

     setter注入:通过setter方法进行注入依赖;

     方法注入:能通过配置方式替换掉Bean方法,也就是通过配置改变Bean方法 功能。

 

 

分享到:
评论

相关推荐

    跟我学spring3(1-7)

    【第五章】Spring表达式语言 之 5.1 概述 5.2 SpEL基础 ——跟我学spring3 【第五章】Spring表达式语言 之 5.3 SpEL语法 ——跟我学spring3 【第五章】Spring表达式语言 之 5.4在Bean定义中使用EL—跟我学spring3 ...

    跟我学spring3(8-13)

    【第十二章】零配置 之 12.2 注解实现Bean依赖注入 ——跟我学spring3 【第十二章】零配置 之 12.3 注解实现Bean定义 ——跟我学spring3 【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring...

    跟我学Spring,Spring3学习资料

    跟我学Spring,Spring3学习资料,讲的还是很详细的,适合新手看

    跟我学spring3

    跟我学spring3 跟我学spring3 跟我学spring3

    Springcloud学习笔记.md

    Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Spring...

    跟我学spring3pdf,高清

    跟我学spring3的pdf,便于学习,供大家分享,一起学习

    跟我学Spring3

    跟我学Spring3

    跟我学spring3 pdf+源码

    跟我学spring3(1-7).pdf 跟我学spring3(8-13).pdf 跟我学spring3-源码.rar 跟我学spring3-项目源码(pointShop)(基于注解).rar 跟我学spring3-项目源码(pointShop)(基于XML配置文件).rar

    Spring框架学习笔记

    学习spring总结的笔记 希望对初学者有所帮助

    spring指南学习笔记

    spring指南学习笔记

    Spring6学习笔记

    Spring6学习笔记,师承老杜

    springsecurity学习笔记

    三更springsecurity学习笔记

    springcloud学习笔记.pdf

    springcloud学习笔记.pdf

    Spring Cloud 学习笔记.pdf

    Spring Cloud 学习入门笔记,全方面实践,包含 spring cloud alibaba 模块

    跟我学spring3(8-13).pdf

    11.2 实现通用层 11.3 实现积分商城层 12.1 概述 12.2 注解实现Bean依赖注入 12.3 注解实现Bean定义 12.4 基于Java类定义Bean配置元数据 12.5 综合示例-积分商城 13.1 概述 13.2 单元测试 集成测试 ——跟我学spring3

Global site tag (gtag.js) - Google Analytics