Spring 学习笔记《依赖注入》—— 配置 applicationContext.xml

28 篇文章 0 订阅

Spring 学习笔记

自己瞎编

学新工具之前,先学会用,再研究他的实现原理。所谓:好读书,不求甚解;每有会意,欣然忘食。反之容易陷于细节而丢了大局。
资料准备了一大堆,所以这里就写点通俗易懂的东西,以便日后自己查阅。

  1. 我们学习的技术90%都是为了少写点代码,目前业界公认的思路就是代码重用。
  2. 为了更好的重用代码,我们总结出许多原则、规则,整理了许多规范(其实就是标出踩过的坑)
  3. 解耦就是个永恒的话题,你不解耦把代码都写死死的,别人还怎么重用?
  4. 既然要解耦,那就得增加工作量啦。提取公共的部分,隔离不相干的功能,每一个模块都只专注处理一个问题。
  5. 面对繁重的劳动,人类当然是靠发明工具来解决啊。难道去提升打字速度吗?
  6. Spring 就是这样的一系列工具。
  7. 先说下万恶之源 new 所有的性能开销和耦合都是因他而起(虽然推锅给new有点违心,我们要申请资源,不new难道凭空冒出来?)
  8. 好吧退一万步说,我们的目的只是要资源,但怎么获得这些资源,就当是些见不得光的脏活,交给 Spring 去干吧。我的双手要干净。

Spring 做什么?

  • 【依赖注入】Dependency Injection 简称 DI

Spring 的核心就是【依赖注入】其他的功能都是围绕着【依赖注入】来实现具体的想法、解决具体的问题。后面我们会讲 XML 主要就是注入规则。在解释依赖注入之前我们先看个栗子。

ClassZ z = new ClassZ();
ClassY y = new ClassY(z);
ClassX x = new ClassY(y);
...// 省略 ClassW 到 ClassD 这一串
ClassC c = new ClassC(d);
ClassB b = new ClassB(c);
ClassA a = new ClassA(b);
  • 依赖 : 我们需要用到 ClassA 但创建A需要参数B,创建B又要参数C层层需要下去。。。这种关系就叫依赖
  • 注入 : 你要什么对象、不用自己new 而是Spring 帮你创建 b再塞给 a,这就是注入
  1. 构造注入:Spring通过构造方法塞,就是【构造注入】
  2. 属性注入:Spring通过setXXX() 方法塞,就是【属性注入】

现在有了【依赖注入】你可以直接向SpringClassA拿来就用爽吧?那些依赖关系Spring都帮你办妥了。
Spring是怎么知道这些依赖关系的哪?答案就是配置 XML, 想要什么东西,配置在XMLSpring自然会按我们的配置创建好,我们只管跟 Spring 要就行了。所以学习使用Spring的核心就是学习怎么配置XML。怎么配?道上有道上的规矩,按规矩来就是了。(插播【控制反转】不要走开,马上回来)

  • 【控制反转】Inversion of Control,简称 IoC

【控制反转】就是一种思路,通过【依赖注入】这个手段来实现。
控制好理解,谁在干脏活,就是谁在掌控那些见不得光的事咯。
反转嘛,以前我自己干,默认是正常流程。那现在我不干了,让别人干,把结果给我。相当于流程翻过来了。坐享其成,何乐而不为呢。

我们做什么?

  • 配置 applicationContext.xml

为了解决前面我们看到的那一连串 A依赖B,B又依赖C的问题,Spring使出了法宝依赖注入,怎么注入不能看心情啊,写在代码里当然不行,想灵活写配置文件啊。因此对新手来说,千言万语不如一个带着注释的applicationContext.xml这个名字不是强制的,只是个惯例。

  • /SpringIoC/src/applicationContext.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
	">
	<!-- ************* Spring容器创建对象是通过定义<bean>标签来实现的 ************* -->
	<!-- 构造器 -->
		<!-- 无参构造 -->
		<bean id="teacher" class="com.jerry.entity.Teacher" />
		<bean id="student" class="com.jerry.entity.Student" />
		
		<!-- 有参构造 -->
		<!-- 通过参数列表来确定调用那个构造方法(原理和重载一样),参数顺序 index 形参名字 name 形参类型 type -->
		<bean id="teacher2" class="com.jerry.entity.Teacher">
			<constructor-arg index="0" name="name" type="String" value="张老强" ></constructor-arg>
			<constructor-arg index="1" name="age" type="Integer" value="30" ></constructor-arg>
			<constructor-arg index="2" name="adder" type="String" value="南天门8号" ></constructor-arg>
			<constructor-arg index="3" name="tel" type="String" value="13838384388" ></constructor-arg>
			<constructor-arg index="4" name="salary" type="Double" value="3000.0" ></constructor-arg>
		</bean>
		
	<!-- 对象工厂 -->
		<!-- 静态工厂 : 直接调用工厂方法,获得生产的对象-->
		<bean id="factoryTeacher" class="com.jerry.factory.TeacherFactory" factory-method="getInstance"></bean>
		
		<!-- 动态态工厂 : 1、配置好工厂bean 2、配置学生bean时通过 factory-bean 属性告诉它用哪个工厂 -->
		<bean id="studentFactory" class="com.jerry.factory.StudentFactory" ></bean>
		<bean id="studentByFactory" class="com.jerry.entity.Student" factory-bean="studentFactory" factory-method="getInstance"/>
	
	<!-- ***************************** 依赖注入 ***************************** -->
	<!-- 上面学会了创建对象。下面讲解怎么注入。因为构造器创建对象也可注入值,但是不如 set 灵活。
		 所以一般我们都是先调用无参构造创建对象,然后 set 属性值 -->
	<bean id="textbook" class="com.jerry.entity.Textbook" >
		<property name="name" value="思想品德"></property>
		<property name="level" value="小学二年级"></property>
	</bean>
	
	<!-- ref 引用其他 bean (【教师】依赖【课本】,这就是前面讲的 【A】依赖【B】的情况)-->
	<bean id="teacherWithRef" class="com.jerry.entity.Teacher">
		<property name="name" value="王大浪"></property>
		<property name="age" value="35"></property>
		<property name="textbook" ref="textbook"></property> 
	</bean>	
	
	<!-- 如果属性是集合 -->
	<bean id="myCollection" class="com.jerry.entity.MyCollection">
		<!-- 基础属性 -->
		<property name="str" value="我有集合属性,我骄傲"></property>
		<!-- 引用属性 : 这个最重要,他就是依赖注入的关键-->
		<property name="teacher" ref="teacher"></property>
		<property name="student" ref="student"></property>
		<!-- 数组 -->
		<property name="arr">
			<array><!-- 数组用 array -->
				<value>111</value>			
				<value>222</value>	
				<!-- 嵌套数组 (为了演示嵌套,所以 arr 声明为 Object数组)-->
				<array>
					<value>333</value>
					<value>444</value>
				</array>		
			</array>
		</property>
		<!-- 列表 -->
		<property name="list">
			<list>
				<value>555</value>			
				<value>666</value>	
			</list>
		</property> 
		<!-- map -->
		<property name="map">
			<map>
				<!-- map的值特殊点,要用 entry -->
				<entry key="aaa" value="777"></entry>
				<entry key="bbb" value="888"></entry>
				<!-- 看到 ref 就要联想到引用 -->
				<entry key="textbook" value-ref="textbook" ></entry>
			</map>
		</property> 
	</bean>	
</beans>
  • /SpringIoC/src/com/jerry/test/TestSpringIoC.java
package com.jerry.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jerry.entity.MyCollection;
import com.jerry.entity.Student;
import com.jerry.entity.Teacher;
import com.jerry.entity.Textbook;

public class TestSpringIoC {

	public static void main(String[] args) {
		// 获取Spring容器
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		// ******************* Spring容器创建对象是通过定义<bean>标签来实现的 *********************
		// --------------- 构造器方法创建 bean ---------------
		// 无参构造
		Teacher teacher= (Teacher)context.getBean("teacher");// 从容器中获取对象
		System.out.println("无参构造,创建 bean : " + teacher.toString());// 查看结果
		
		// 有参构造
		Teacher teacher2= (Teacher)context.getBean("teacher2");// 从容器中获取对象
		System.out.println("有参构造,创建 bean : " + teacher2.toString());// 查看结果
		
		// --------------- 工厂方法创建 bean ---------------
		// 静态工厂方法创建 bean
		Teacher teacherByFactory = (Teacher)context.getBean("factoryTeacher");
		System.out.println("静态工厂,创建 bean : " + teacherByFactory);
		
		// 动态态工厂方法创建 bean
		Student studentByFactory = (Student)context.getBean("studentByFactory");
		System.out.println("动态工厂,创建 bean : " + studentByFactory);
		
		// ********************************** 依赖注入 *************************************
		// 无参构造 + 基础属性注入
		Textbook textbook= (Textbook)context.getBean("textbook");// 从容器中获取对象
		System.out.println("基础属性注入,创建 bean : " + textbook.toString());// 查看结果
		
		// 无参构造 + 引用属性注入
		Teacher teacherWithRef= (Teacher)context.getBean("teacherWithRef");// 从容器中获取对象
		System.out.println("引用属性注入,创建 bean : " + teacherWithRef.toString());// 查看结果
		
		// 无参构造 + 属性集合注入
		MyCollection myCollection= (MyCollection)context.getBean("myCollection");// 从容器中获取对象
		System.out.println("集合属性 : " + myCollection.toString());// 查看结果
	}
}

看看效果

一月 20, 2019 8:20:17 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@14e8b5fe: startup date [Sun Jan 20 20:20:17 CST 2019]; root of context hierarchy
一月 20, 2019 8:20:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]

无参构造,创建 bean : Teacher [name=李老师, age=27, adder=鸟不拉屎村, tel=10086, salary=5000.0, textbook=null]

有参构造,创建 bean : Teacher [name=张老强, age=30, adder=南天门8号, tel=13838384388, salary=10000.0, textbook=null]

静态工厂,创建 bean : Teacher [name=李老师, age=27, adder=鸟不拉屎村, tel=10086, salary=5000.0, 
textbook=课本 [name=数学课本, level=大一]]

动态工厂,创建 bean : 同学 [ name=王二狗, age=18, adder=天堂路1号, tel=13866666666, chineseScore=null, mathScore=null, englishScore=null, 
textbook=课本 [name=数学课本, level=大一]]

基础属性注入,创建 bean : 课本 [name=思想品德, level=小学二年级]

引用属性注入,创建 bean : Teacher [name=王大浪, age=35, adder=鸟不拉屎村, tel=10086, salary=5000.0, 
textbook=课本 [name=思想品德, level=小学二年级]]

集合属性 : 对象含集合属性 [str=我有集合属性,我骄傲, arr=[111, 222, [Ljava.lang.Object;@58d872f5], 
list=[555, 666], 
map={aaa=777, bbb=888, textbook=课本 [name=思想品德, level=小学二年级]}, 
teacher=Teacher [name=李老师, age=27, adder=鸟不拉屎村, tel=10086, salary=5000.0, textbook=null], 
student=同学 [ name=三毛, age=82, adder=流浪者居无定所, tel=110, chineseScore=null, mathScore=null, englishScore=null, 
textbook=null]]

资源文件

所需的jar包,这是POM

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.jerry</groupId>
  <artifactId>SpringIoC</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringIoC Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
    <spring.version>5.1.1.RELEASE</spring.version>
  </properties> 

  <dependencies>
    <!-- spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
  </dependencies>
  
  <build>
    <finalName>SpringIoC</finalName>
  </build>
</project>

Spring 学习笔记《依赖注入》源文件

https://download.csdn.net/download/jx520/10929168

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值