我理解的Spring(一)基础

本文深入浅出地介绍了Spring框架的基本概念及其优势,包括其如何简化开发流程、管理对象依赖关系和集成其他框架等内容。此外,还详细讲解了Spring容器的工作原理、对象创建方式以及依赖注入等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

简单谈一谈对spring的理解。
若有错误,还望指正!如需转载,标明出处!谢谢。

二、Spring基础

1. 什么是Spring

一个开源的简化开发的框架。

2. Spring的优势

2.1 简化开发

Spring对常用的功能进行了封装和简化,简化了代码开发,提升了开发效率。
比如Spring JDBC是对JDBC的封装。通过简单的配置,可实现JDBC的功能,还不用考虑获取连接、关闭连接等情况。

2.2 管理对象

Spring提供了一个容器,帮我们管理对象,如创建对象、管理对象间的依赖关系。
如此,降低了对象间的耦合度,便于代码维护。

2.3 集成其他框架

Spring还提供了对其他框架的集成功能,当现有功能不够用的时候,可以将其他优秀框架集成进来。
比如任务调度 Quartz。

3. Spring容器

3.1 准备工作

使用Spring需要先导入jar包,用maven导入spring-webmvc。
在resources下创建spring.xml文件。此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:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	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/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
	
</beans>

3.2 创建对象

Spring创建对象有多种方式,包括使用无参构造器创建、使用静态工厂方式创建、使用实例工厂方式等。无参构造器方式是需要重点掌握的,下面会详细说明步骤。另外的方式也会简要说明。

3.2.1 创建类(使用无参构造器)

在java的spr包下创建一个实体类Student。该类中包含一个无参的构造方法及一个普通的say方法。构造方法用于表示对象是否创建,say()用于展示该对象是否成功创建且可使用。
代码如下。

package spr;

public class Student {
	public Student(){
		System.out.println("Student()");
	}
	public void  say(){
		System.out.println("say()");
	}
}
3.2.2 编写Spring配置

在spring.xml配置文件的beans根节点中,敲下如下代码。

<bean id="stu" class="spr.Student"></bean>

id是bean的唯一标识,要求唯一。
class为类的全限定名。

3.2.3 启动Spring并测试

此处使用junit进行测试。
启动Spring容器使用的是ApplicationContext接口,它的实现类为ClassPathXmlApplicationContext。
代码如下。

package mytest;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spr.Student;

public class MyTest {
	@Test
	public void t1(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
		Student stu = ac.getBean("stu",Student.class);
		stu.say();
	}
}
3.2.4 测试结果

如下为测试结果,可见容器是调用了Student类的无参构造器创建对象的,并且对象成功创建,并调用了say().

Student()
say()
3.2.5 使用静态工厂方式

以上是使用无参构造器的方式创建对象,还可以使用静态工厂的方式创建对象。
spring容器中有如下代码。

<bean id="c1" class="java.util.Calendar" factory-method="getInstance"></bean>

util下的Calendar的getInstance是静态方法,此处需要使用factory-method。
测试对象

@Test
public void t2(){
	ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
	Calendar c1 = ac.getBean("c1",Calendar.class);
	System.out.println(c1);
}

测试结果

java.util.GregorianCalendar[time=1615282039257,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=2,WEEK_OF_YEAR=11,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=68,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=27,SECOND=19,MILLISECOND=257,ZONE_OFFSET=28800000,DST_OFFSET=0]

根据测试结果,可见使用对象成功创建!

3.2.6 使用实例工厂方式

使用实例工厂需要类中有一个方法能返回一个类的实例。代码如下。

public class Student {
	public Student  say(){
		System.out.println("say()");
		return new Student();
	}
}

spring.xml:
通过spr.Student的say获取一个Student的实例stu2

<bean id="stu" class="spr.Student"></bean>
<bean id="stu2" factory-bean="stu" factory-method="say"></bean>

测试:

@Test
	public void t3(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
		Student stu2 = ac.getBean("stu2",Student.class);
		System.out.println(stu2);
	}

测试结果:

say()
spr.Student@86be70a

3.3 作用域

默认情况下,容器对bean只会创建一个实例,即单例singleton。但是我们可以通过修改scope属性为prototype来改变他的作用域,使得它可以创建多个实例。scope的值还可以是request等,此处暂不详述。
当scope为prototype时,每次获取的对象都是一个新的对象。

容器启动时,会默认创建作用域为singleton的实例。

3.4 生命周期

初始化方法:
通过init-method来指定初始化方法,指定后的方法会在类初始化时调用。
销毁方法:
通过destroy-method来指定销毁方法,指定后的方法会在实例销毁时调用。

Spring容器关闭时,会销毁对象,销毁对象前会调用销毁方法。

3.5 延迟加载

通过lazy-init来指定是否延迟加载。为true表示延迟加载。
容器在启动时,会自动加载作用域为singleton的实例,通过设置lazy-init可以让容器先不自动加载,在调用该实例时再加载。

4. IOC

4.1 什么是IOC

IOC即控制反转,对象之间的依赖关系由Spring容器控制。

4.2 DI

DI即为依赖注入。

IOC为目标,DI为手段。

4.3 Set注入

现有两个类A和B,需要将A注入到B中,需要在B中写一个setA的方法,通过set的方式将A注入进来。代码如下。
A类:

package ioc;
public class A {
	public A() {
		System.out.println("A()");
	}
}

B类:

package ioc;
public class B {
	private A a;
	
	public B(){
		System.out.println("B()");
	}
	//set注入
	public void setA(A a){
		this.a = a;
		System.out.println("setA()");
		System.out.println(a);//测试A是否成功注入
	}
}

spring.xml:
property元素表示用set方式注入,name指属性名,ref指属性值,注入式,会将name的首字母大写,并在前面加上set,此处即setA。

<bean id="aa" class="ioc.A"></bean>
 	
<bean id="bb" class="ioc.B">
   <property name="a" ref="aa"></property>
</bean>

启动容器:
自动加载两个单例类,完成注入

@Test
public void t1(){
	ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
}

结果:
成功将A注入,并打印出A。

A()
B()
setA()
ioc.A@1b68ddbd

4.4 构造器注入

同样是A和B两个类,只是B中不是setA而是有一个有参数的构造器,通过该构造器进行A的注入。代码如下:
A类:

package ioc;
public class A {
	public A() {
		System.out.println("A()");
	}
}

B类:

package ioc;
public class B {
	private A a;
	
	public B(){
		System.out.println("B()");
	}
	//constructor注入
	public B(A a){
		this.a = a;
		System.out.println("B(A a)");
		System.out.println(a);//打印A
	}
}

springx.xml
constructor-arg元素表示是构造器注入,index属性指参数的下标,从0开始,ref指属性值。

<bean id="aa" class="ioc.A"></bean>
 	
<bean id="bb" class="ioc.B">
    <constructor-arg index="0" ref="aa"></constructor-arg>
</bean>

启动容器:

@Test
	public void t1(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
	}

结果:

A()
B(A a)
ioc.A@1e965684

4.5 自动装配

指的是Spring容器按照某种规则,自动建立对象之间的依赖关系。
容器默认情况下,不会自动装配。要使用自动装配,通过autowire属性配置。
容器实质上仍然需要调用set方式或构造器方式注入。只是这个步骤通过配置autowire属性让容器自己去做了,不需要我们去写。

4.5.1 byName

容器依据属性名来查找对应的bean,然后调用对应set方法完成注入。
a.如果找不到对应的bean,注入null。
b.不可能找到多个bean的情况。因为id唯一。

4.5.2 byType

容器依据属性类型来查找对应的bean,然后调用对应set方法完成注入。
a.如果找不到对应的bean,注入null。
b.如果找到多个对应的bean,报错。

4.5.3 constructor

容器依据属性类型来查找对应的bean,然后调用对应构造器方法完成注入。
与byType相似,都是根据属性的类型去查找bean。
a.如果找不到对应的bean,注入null。
b.如果找到多个对应的bean,报错。

结束语

因为篇幅的原因,此处就写这么多,数据注入、注解等在下一章记录。
平时总觉得spring也没有什么,当去静下心记录的时候就会感觉,哇,怎么还没完呢,好多!哈哈哈,这还是没有剖析源码,敬畏代码,敬畏技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值