`

跟我学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方法 功能。

 

 

分享到:
评论

相关推荐

    Springcloud学习笔记.md

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

    跟我学spring3pdf,高清

    《跟我学Spring3》是一本深入浅出的Spring框架学习指南,主要针对Spring 3.x版本进行讲解。这本书旨在帮助初学者和有一定经验的开发者更好地理解和应用Spring框架,提升其在实际开发中的技能。PDF文档提供了清晰的...

    跟我学spring3

    在《跟我学Spring3》中,你将深入学习以下主题: 1. Spring Boot:一个快速启动Spring应用的框架,简化了配置并提供了内置的服务器和依赖管理。 2. Spring MVC:学习如何使用Spring MVC构建RESTful服务,处理HTTP...

    跟我学Spring,Spring3学习资料

    关于Spring3学习资料,本材料旨在为新手提供系统学习Spring3的资源和实例。在内容组织上,涵盖以下几个主要部分: ### 1. IoC(控制反转)与DI(依赖注入) - **IoC基础:** IoC是Spring的核心概念之一,通过它,...

    跟我学Spring3

    《跟我学Spring3》这本书是针对Java开发人员深入学习Spring框架第三版的一份教程。Spring作为Java企业级应用开发中的核心框架,它以其强大的功能、灵活性和模块化设计深受开发者喜爱。Spring3版本在前一版本基础上...

    开涛 跟我学spring3 pdf+源码

    总的来说,《跟我学Spring3》结合PDF教程和源码,为Java开发者提供了一套完整的Spring学习路径,无论你是初学者还是有一定经验的开发者,都能从中受益匪浅。通过学习和实践,你可以掌握Spring的核心技术和最佳实践,...

    Spring框架学习笔记

    这份"Spring框架学习笔记"涵盖了Spring框架的基础知识、核心组件以及高级特性,对于初学者来说是一份宝贵的资料。 一、Spring框架概述 Spring框架是为了解决企业应用开发的复杂性而设计的,它提供了一个全面的基础...

    跟我学spring3(1-13)

    《跟我学Spring3》是一本深入浅出介绍Spring框架的电子书,分为两部分,分别是“跟我学Spring3(8-13).pdf”和“跟我学Spring3(1-7).pdf”,全面覆盖了Spring框架的核心概念和技术。Spring作为Java开发中的主流框架,...

    开涛系列—跟我学spring3 pdf+学习源码+项目源码

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

    跟我学spring3 pdf+源码

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

    跟我学spring3 .pdf

    《跟我学Spring3》这本书是针对Spring框架进行深入解析的一本教程,涵盖了Spring的核心特性,包括IoC(Inversion of Control,控制反转)、DI(Dependency Injection,依赖注入)、AOP(Aspect-Oriented Programming...

    Spring6学习笔记

    Spring6学习笔记,师承老杜

    springcloud学习笔记.pdf

    Spring Cloud 学习笔记 本笔记主要介绍了从单体架构到微服务架构的演变过程,以及 Spring Cloud 中的微服务架构搭建。下面是本笔记的详细知识点总结: 一、单体架构 单体架构是指整个系统只有一个工程,打包往往...

    spring指南学习笔记

    标题和描述均提到了“spring指南学习笔记”,这意味着文档聚焦于Spring框架的学习心得与关键概念。Spring是一个开源的Java企业级应用框架,以其强大的依赖注入(Dependency Injection, DI)和面向切面编程(Aspect ...

    跟我学spring

    标题“跟我学spring”和描述“spring 的使用,每个知识点和项目中的运用,20章的介绍。”暗示这是一份详细介绍Spring框架使用方法的教程或手册,覆盖了Spring的各个方面,并以实例为导向,深入探讨了每个知识点在...

Global site tag (gtag.js) - Google Analytics