SpringMVC(1)

本文详细介绍了Spring框架的核心概念,包括框架的定义、Spring框架的组成、特别是IOC容器的工作原理。通过一个SpringHelloWorld示例,展示了如何创建和使用IOC容器,以及配置文件的应用。同时,讲解了JavaBean规范、Bean的作用域、生命周期管理和延迟实例化。最后,文章通过一个具体的例子阐述了Spring的依赖注入(DI)功能。
摘要由CSDN通过智能技术生成

Spring

1、什么是框架

框架是软件半成品!使用框架可以简化应用软件的开发,提高开发效率。
使用框架必须遵守框架的使用约定!

2、什么是Spring框架

由Spring开源社区开发维护的 “系列” 软件框架。
其核心组件:IOC/AOP

3、IOC容器

IOC,控制反转:由外部容器环境创建管理 “对象组件” ,交给 应用程序 使用。

主动控制:由应用程序控制管理 “对象组件”

Spring最基本的功能就是IOC容器,也称为Spring容器,Spring IOC 容器。

Spring IOC 容器:控制创建管理“对象组件”的容器。

4、Spring Hello World

1、导入 Spring IOC 组件包

        <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.2.1.RELEASE</version>
		</dependency>
		
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

spring-context的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"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	
</beans>

2、创建被 Spring IOC 管理的对象组件 类。

3、创建配置文件:通知 Spring 管理哪个对象组件。

4、创建应用程序

  1. 创建 Spring 容器,读取 Spring 配置文件
  2. 从 Spring 容器中获取,被 Spring 管理的对象(控制反转)
  3. 调用对象的方法(验证),输出 Hello World!
    在这里插入图片描述
    Hello World 示例:
    在这里插入图片描述
    代码实现:
    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"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- class用于通知SpringSpring会读取class的值,在Spring内部用反射创建对象 -->
	<!-- id用于标识识别对象,id不能重复 -->
	<bean id="demo" class="day01.Demo"></bean>
</beans>

Demo类:(由Spring管理的类)

package day01;

public class Demo {
	public void test() {
		System.out.println("Hello World!");
	}
}

Demo01:(模拟应用程序)

package day01;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Spring IOC 容器基本功能演示
 * @author DELL
 *
 */
public class Demo01 {
	public static void main(String[] args) {
		//1.创建Spring容器对象,参数是Spring配置文件
		//  Spring会读取配置文件,根据配置文件 利用反射 创建被管理的对象组件。
		ClassPathXmlApplicationContext ctx = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		//2.从Spring容器中得到被管理的对象组件
		Demo obj = (Demo)ctx.getBean("demo");
		obj.test();
	}
}

5、Java Bean (爪哇豆子)

Bean:豆子

JavaBean:符合一定规范的Java对象,JavaBean规范不是语法规范,违反不会有编译错误。

一般规范有:

1.需要定义包 package

2.有无参构造器

3.需要实现序列化接口

4.包含使用 getXxx、setXxx 声明的“Bean属性” xxx

  1. Bean属性(Bean Property)就是指 getXxx、setXxx 方法
  2. 对象属性(Object Field)是指对象的实例变量

例:

class Person{
    private String name = "狄仁杰";  // 实例变量、对象属性 name
    
    String getName(){  // Bean属性 name
        return name;
    }
    void setName(String name){  // Bean属性 name
        this.name = name;
    }
    String getLastName(){  //Bean属性 lastName
        return name.substring(0,1);
    }

}

Spring容器也称为JavaBean容器,Spring建议被IoC容器管理的对象符合JavaBean规范.(实际上可以不遵守!)

6、Bean标签别名

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- class用于通知SpringSpring会读取class的值,在Spring内部用反射创建对象 -->
	<!-- id用于标识识别对象,id不能重复 -->
	<bean id="demo" class="day01.Demo"></bean>
	
	<!-- alias:别名,曾用名 -->
	<alias name="demo" alias="demo1"/>
	
	<!-- Bean 标签的 id 属性和 name 属性的作用一样 -->
	<!-- 大多数使用 id 属性 -->
	<bean name="demo2" class="day01.Demo"></bean>
</beans>

测试:

package day01;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestCase {
	
	ClassPathXmlApplicationContext ctx; //实例变量,Java没有全局变量
	
	@Before // init() 会在测试案例之前执行,一般用来初始化测试案例的环境,如:初始化 Spring 容器。
	public void init() {
		ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
	}
	
	@After // destroy() 会在测试案例之后执行,用户与回收系统资源,如:关闭 Spring 容器。
	public void destroy() {
		ctx.close();
	}
	
	@Test
	public void testDemo() {
		/*
		 * Spring Hello World
		 */
		Demo demo = (Demo)ctx.getBean("demo");
		demo.test();
	}
	
	@Test
	public void testAlias() {
		/*
		 * 测试 在 Spring 中为JavaBean对象声明别名
		 */
		Demo demo = (Demo)ctx.getBean("demo1");
		demo.test();
	}
	
	@Test
	public void testName() {
		/*
		 * 测试 Spring 中用 name 属性标识识别对象
		 */
		Demo demo = (Demo)ctx.getBean("demo2");
		demo.test();
	}
	
	@Test
	public void testGetBean() {
		/*
		 * Spring 容器提供了重载的 getBean 方法,可以自动完成类型转换,不用写强制转型
		 */
		// 第一个参数是 id 属性值,第二个参数是 Bean 对象的类型
		Demo demo = ctx.getBean("demo", Demo.class);
		demo.test();
	}
	
}

7、Bean的作用域(Scope)

1、Spring 容器默认情况下按照“单例”管理对象。

  1. 单例:在软件中对象是唯一的一个实例的现象。
  2. 多次调用 getBean 获得的是同一个对象的引用。

2、Spring 使用 bean 标签的 scope 属性可以指定多例。

3、Spring 默认情况下单例方式可以提高性能。

<!-- scope 属性声明“原型prototype”创建多个实例,每次调用 getBean 的时候都会创建一个新实例 -->
	<bean id="myBean" class="day01.Demo" scope="prototype"></bean>
    @Test
	public void testMyBean() {
		/*
		 * 使用“scope=prototype”创建多个对象实例
		 * 每次调用 getBean 方法都会创建一个对象实例
		 */
		Demo d1 = ctx.getBean("myBean", Demo.class);
		Demo d2 = ctx.getBean("myBean", Demo.class);
		System.out.println(d1==d2); // false
	}

8、Bean的生命周期管理方法

1、指定初始化回调方法

<bean id="exampleBean" class="com.foo.ExampleBean "
init-method = "init" >
</bean>

2、指定销毁回调方法,仅适用于 singleton 模式的 bean

<bean id="exampleBean" class="com.foo.ExampleBean"
destroy-method = "destroy" >
</bean>

    <!-- init-method 设置创建对象以后执行的方法 -->
	<!-- destroy-method 设置关闭容器销毁对象时执行的方法 -->
	<!-- 这两个方法会自动执行 -->
	<!-- destroy-method:只对单例对象有效,多例对象上设置无效 -->
	<bean id="logTool" class="day01.LogTool" init-method="open" destroy-method="close"></bean>

提示:指定 销毁回调方法,仅适用于singleton模式的bean。

代码演示:

LogTool:

package day01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;

public class LogTool {
	String fileName = "demo.log";
	PrintWriter out;

	public void open() throws Exception {
		// 打开文件
		// 覆盖写
		// out = new PrintWriter(fileName);
		// 追加写
		out = new PrintWriter(new FileOutputStream(fileName, true));
		System.out.println("打开文件!");
	}

	public void write(String log) {
		out.println(log);
		out.flush();
	}

	public void close() {
		out.close();
		System.out.println("关闭文件!");
	}

}

TestCase:

@Test
	public void testLogTool() {
		/*
		 * 测试对象声明周期管理方法,
		 * init-method 设置创建对象以后执行的方法
		 * destroy-method 设置关闭容器销毁对象时执行的方法
		 */
		LogTool tool = ctx.getBean("logTool", LogTool.class);
		tool.write("这是一个测试!");
		tool.write("再试试!");
	}

反例: 测试 多个实例情况下不会执行 destroy-method 的方法

    <!-- Spring作为多例管理的对象,不会执行 destroy-method -->
	<bean id="demoBean" class="day01.DemoBean" scope="prototype"
		init-method="init" destroy-method="destroy"></bean>

DemoBean类:

package day01;

/**
 * 测试:多实例的时候,关闭容器时,不会执行 destroy-method 的方法
 * @author DELL
 *
 */
public class DemoBean {
	
	public void init() {
		System.out.println("Call init()");
	}
	
	public void destroy() {
		System.out.println("Call destroy()");
	}
	
}

测试:

@Test
	public void testDestroy() {
		/*
		 * scope="prorotype"
		 * 多个实例情况下不会执行 destroy-method 的方法
		 * 每次创建对象,都会执行对象的 init-method
		 */
		DemoBean bean = ctx.getBean("demoBean", DemoBean.class);
		DemoBean bean2 = ctx.getBean("demoBean", DemoBean.class);
		System.out.println(bean2);
	}

测试结果为:
在这里插入图片描述

9、Bean延迟实例化

在 ApplicationContext 实现的默认行为就是在启动时将所有 singleton bean(单例对象) 提前进行实例化。

如果不想让一个 singleton bean(单例对象) 在ApplicationContext初始化时被提前实例化,可以使用<bean>元素的lazy-init="true"属性改变。

一个延迟初始化bean将在第一次被用到时实例化
<bean id="exampleBean" lazy-init="true" class="com.foo.ExampleBean"/>

在顶级的<beans/>元素中的default-lazy-init属性,可以为容器所有<bean>指定延迟实例化特性

对于很少使用的单例对象,可以设置懒初始化,这样可以最大化的节省内存。

案例:

<!-- 设置懒惰加载,Spring会在第一次使用对象时候创建对象,如果不使用对象,就不会创建对象。 -->
	<bean id="demoBean1" class="day01.DemoBean" lazy-init="true" init-method="init"></bean>
@Test
	public void testLazyInit() {
		/*
		 * 测试单例对象的懒惰加载方式,在第一次调用 getBean 方法时候创建对象。
		 * 如果不调用 getBean 方法,就不会创建 Bean 对象。
		 */
		//DemoBean bean = ctx.getBean("demoBean1", DemoBean.class);
		//DemoBean bean1 = ctx.getBean("demoBean1", DemoBean.class);
		System.out.println("Lazy-init");
	}
	

DI:依赖注入

IOC容器不仅可以管理对象,还可以利用DI功能为对象注入Bean属性。

对象的依赖:一个对象在执行功能期间需要使用另外一个对象,称为对象的依赖。

属性注入:将一个对象作为属性注入给另外对象。

案例图示:
在这里插入图片描述
代码实现:

Spring配置文件:

<!-- 利用 property 注入依赖的对象 -->
	<bean id="qiang" class="day01.Worker">
		<!-- 将 斧子Bean 对象注入到 Bean属性中 -->
		<property name="axe" ref="axe1"></property>
	</bean>
	<bean id="axe1" class="day01.Axe"></bean>

Worker:

package day01;

public class Worker {
	
	private String name = "光头强";
	private Axe axe;
	
	public void setAxe(Axe axe) {
		this.axe = axe;
	}
	
	public void work() {
		// 字符串连接的时候自动调用了 Axe 的 toString 方法
		System.out.println(name+"使用"+axe+"砍树!");
	}
	
}

Axe:

package day01;

public class Axe {
	
	@Override
	public String toString() {
		return "金斧子";
	}
	
}

测试:

@Test
	public void testWork() {
		/*
		 * 测试Spring提供的 DI 功能
		 */
		Worker qiang = ctx.getBean("qiang", Worker.class);
		qiang.work();
	}
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值