零基础学习-spring框架

Posted A 小码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零基础学习-spring框架相关的知识,希望对你有一定的参考价值。

Spring框架

1. spring官网

官网:https://spring.io/

2. Spring框架

框架(Framework):一系列的jar包,同时约定了实现某个功能的编程方式,可能与原有的编程方式并不相同!每个框架都解决了某些特定的问题!

Spring框架解决的问题:解决了创建和管理对象的问题,实现了解耦!

简单的创建对象的语法大致是:

User user = new User();

使用以上方式创建对象不便于实现解耦!

解耦:解除对象的之间的耦合!即降低对象之间的依赖关系!

依赖:在一个对象的工作过程中,需要使用到另一个对象,则称之为依赖另一个对象!

例如:

public class UserJdbcDao {
	public void login() {
		// 连接数据库
		// 执行SQL语句
	}
}

public class UserLoginServlet {
	public UserJdbcDao userJdbcDao = new UserJdbcDao();
	public void doPost() {
		userDao.login();
	}
}

在以上代码中,UserLoginServlet就是依赖于UserJdbcDao的!

在以上代码的基础之上,如果UserJdbcDao使用的技术需要更换,或者出于其它的原因,这个类已经不再满足项目的需求,需要换成另一个类,或使用另一种技术来实现,则可能创建新的UserMyBatisDao来替换原有的UserJdbcDao

如果需要替换,则以上代码中public UserJdbcDao userJdbcDao = new UserJdbcDao();就需要被替换为:

public UserMyBatisDao userMyBatisDao = new UserMyBatisDao();

如果这个项目中,有多个Servlet组件都使用了UserJdbcDao,则需要替换多次!

所以,如果要把UserJdbcDao替换为UserMyBatisDao,整个项目中需要调整的代码可能较多!通常,就称之为“耦合度太高”!

首先,可以定义一个接口:

public interface UserDao {
	void login();
}

然后,使得UserJdbcDaoUserMyBatisDao都实现以上接口!则后续需要使用DAO对象时,可以声明为:

// 使用接口声明,创建某个实现类的对象
public UserDao userDao = new UserJdbcDao();

则后续需要替换时,该对象的声明语句是不用调整的!

接下来,还可以使用设计模式中的工厂模式来解决创建对象的问题:

public class UserDaoFactory {
	public static UserDao newInstance() {
		return new UserJdbcDao();
	}
}

则此前的代码可以进一步调整为:

public UserDao userDao = UserDaoFactory.newInstance();

在任何一个Servlet中,需要使用DAO时,都使用以上代码即可,以上代码中根本就没有出现哪个实现类的名称,如果需要替换实现类,以上代码根本就不需要调整!需要调整的只有工厂类中的方法的返回值而已!

也可以看到,在Servlet类中,根本就不需要出现某个DAO类的名称,则可以称之为UserLoginServlet不依赖于UserJdbcDao或UserMyBatisDao!也就解除了UserLoginServletUserJdbcDaoUserMyBatisDao之间的耦合度!

在以上做法中,就使用到了接口、工厂类,它们是解耦的核心!但是,在实际开发某个项目时,不可能为大量的类都去创建对应的接口与工厂类!所以,就出现了Spring框架!可以简单的将Spring框架理解为一个大型工厂,专门用于创建和管理项目中所需的类的对象,当需要使用某个对象时,从Spring框架中获取即可,而不再是自行创建对象、自行编写工厂等!

3. 通过无参数构造方法,使用Spring创建对象,并从Spring中获取对象

首先,创建Maven Project,创建过程中,勾选Create a simple ProjectGroup Id填写cn.teduArtifact Id填写Spring01Packaging选择war

如果仅仅只是使用Spring,以上Packaging并不需要选择war,选择jar也是可以的!

创建的项目默认没有web.xml文件,需要先生成该文件,否则,项目会报错!

创建完成后,需要在pom.xml中添加org.springframeworkspring-webmvc依赖:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.3.8.RELEASE</version>
</dependency>

如果只是使用Spring框架的内容,添加spring-context依赖即可,并不需要spring-webmvc,由于后续将学习SpringMVC框架,在spring-webmvc中包含了spring-context,所以,也可以直接使用spring-webmvc

此次所添加的依赖只要是4.2或以上版本均可!可选版本有:4.3.14.3.10,4.3.124.3.14等。

然后,从http://doc.tedu.cn/config/spring-context.zip下载Spring配置文件,解压后得到applicationContext.xml文件,将该文件复制到项目的src/main/resources下。

假设需要通过Spring创建Date类的对象,则在applicationContext.xml中添加配置:

<!-- 需要获取Date类的对象 -->
<!-- id属性:名称,后续将根据这个名称获取对象 -->
<!-- class属性:创建哪个类的对象 -->
<bean id="date" class="java.util.Date"></bean>

最后,创建可运行的类,添加代码:

ClassPathXmlApplicationContext ac
		= new ClassPathXmlApplicationContext(
			"applicationContext.xml");
	
Date date = (Date) ac.getBean("date");
	
System.out.println(date);
	
ac.close();

运行,即可看到输出的日期时间。

以上做法要求该类存在无参数构造方法!

4. 通过静态工厂方法创建并获取对象【不常用】

某些类也许没有无参构造方法,但是,可能存在某个被static修饰的方法,并且该方法就返回当前类型的对象,例如Calendar类中就存在:

public static Calendar getInstance() { ...

以上getInstance()方法就是Calendar类的静态工厂方法!

如果需要使用Spring管理Calendar的对象,则需要在applicationContext.xml中配置:

<!-- 2. 通过静态工厂方法创建对象 -->
<!-- factory-method属性:工厂方法的名称 -->
<bean id="calendar" class="java.util.Calendar"
	factory-method="getInstance"></bean>

5. 通过实例工厂创建并管理对象【不常用】

假设某个类并不满足以上2种方式创建对象,并且,存在另一个类,类中有某个方法可以创建对象,例如:

public class UserDao {
	public UserDao(String s) {
	}
}

public class UserDaoFactory {
	public UserDao newInstance() {
		return new UserDao(null);
	}
}

则配置为:

<!-- 3. 通过实例工厂方法创建对象 -->
<!-- factory-bean属性:工厂对象的bean-id -->
<!-- factory-method属性:工厂方法的名称 -->
<bean id="userDaoFactory" 
	class="cn.tedu.spring.UserDaoFactory"></bean>
<bean id="userDao" class="cn.tedu.spring.UserDao"
	factory-bean="userDaoFactory" 
	factory-method="newInstance"></bean>

6. 由Spring管理的对象的作用域【仅了解】

由Spring管理的对象,默认都是单例的!

单例:在同一时间,某个类的对象一定只有1个!

如果需要配置对象是否单例,可以:

<!-- scope属性:配置类的对象的作用域,是否为单例,默认值是singleton,当配置为prototype时表示非单例 -->
<bean id="user" class="cn.tedu.spring.User"
	scope="prototype" />

如果是自行设计单例模式,可以是例如:

public class User {

	private static User user = new User();

	private User() {
	}

	public static User getInstance() {
		return user;
	}

}

由于被获取的对象是使用了static修饰的,所以,单例的类的对象,都是静态的,也就是具有常驻内存的特点!则单例的对象的作用域就是整个程序加载这个类开始,直至程序运行结束!而非单例的对象的作用域就是普通的变量的作用域!

另外,单例模式还区分为懒汉式单例饿汉式单例,如果是懒汉式单例模式,只会在获取对象的前一刻才创建对象,如果是饿汉式单例模式时,则项目运行之初就已经创建了对象!

默认情况下,由Spring管理的单例的对象都是饿汉式的!可以在Spring的配置文件中添加配置:

<!-- lazy-init属性:是否懒汉式加载,取值可以是布尔值 -->
<bean id="user" class="cn.tedu.spring.User"
	scope="singleton"
	lazy-init="true" />

注意:必须是单例模式的基础之上,再讨论是否懒加载的问题!

关于懒汉式单例的实现代码:

public class User {

	private static User user;
	private static final Object lock = new Object();

	private User() {
	}

	public static User getInstance() {
		if (user == null) {
			sychronized(lock) {
				if (user == null) {
					user = new User();
				}
			}
		}
		return user;
	}

}

7. 由Spring管理的对象的生命周期【不常用】

对象的生命周期就是从创建到销毁的历程。

Servlet为例,从创建到销毁的过程中,还会执行init()service()destroy()方法,其中,init()方法是创建对象之后就会立即执行的初始化方法,并且,只会执行1次,而service()方法是每次接收到请求后都会执行的方法,可能执行若干次,destroy()方法是销毁对象的前一刻执行的方法,也只会执行1次!

在Java EE中的Servlet组件是由容器(例如Tomcat)创建并管理的!作为程序员,必须知道哪些方法在什么时候被调用,才可以正确的重写这些方法,从而决定“什么时候应该做什么事情”!

当使用了Spring框架后,对象的管理权也是交给了框架的!为了保证在初始化时能定制所需要执行的任务,在销毁之前能释放资源等,也可以在类中声明对应的生命周期方法:

public class User {

	public User() {
		super();
		System.out.println("创建User对象!");
	}
	
	public void onCreate() {
		System.out.println("User.onCreate()");
	}
	
	public void onDestroy() {
		System.out.println("User.onDestroy()");
	}
	
}

在配置时,添加init-methoddestroy-method属性的配置:

<!-- init-method:生命周期方法的初始化方法的名称 -->
<!-- destroy-method:生命周期方法的销毁方法的名称 -->
<bean id="user" class="cn.tedu.spring.User"
	init-method="onCreate"
	destroy-method="onDestroy" />

以上是关于零基础学习-spring框架的主要内容,如果未能解决你的问题,请参考以下文章

零基础带你看Spring源码——IOC控制反转

喜迎2021新年,Spring5/SpringBoot/SpringCloudAlibaba,基础框架视频教学免费领取!

零基础大数据学习框架

从零开始手写 spring ioc 框架,深入学习 spring 源码

从零开始手写 spring ioc 框架,深入学习 spring 源码

Python零基础该如何学习