Spring 简介

①Spring是一个开源框架

②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,有效的降低代码的耦合度,极大的方便项目的后期维护、升级和扩展。

③Spring是一个IOC(DI)和AOP容器框架。

④Spring的优良特性

[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API

[2]控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。

[3]依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。

[4]面向切面编程:Aspect Oriented Programming——AOP

[5]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期

[6]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

    [7]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)

2、Spring的模块介绍

spring 两个项目maven可以互相依赖么 spring与maven啥关系_jar

Spring框架分为四大模块:xxx为版本号
Core核心模块。负责管理组件的Bean对象

spring-beans-xxx.jar

spring-context-xxx.jar

spring-core-xxx.jar

spring-expression-xxx.jar

面向切面编程

spring-aop-xxx.jar

spring-aspects-xxx.jar

数据库操作

spring-jdbc-xxx.jar

spring-orm-xxx.jar

spring-oxm-xxx.jar

spring-tx-xxx.jar

spring-jms-xxx.jar

Web模块

spring-web-xxx.jar

spring-webmvc-xxx.jar

spring-websocket-xxx.jar

spring-webmvc-portlet-xxx.jar

这里是引用,原文链接:

使用Maven 搭建一个简单的Spring项目

  1. 首先建立一个Maven项目,如果电脑上没有Maven的先安装Maven,我用的编码工具是STS

spring 两个项目maven可以互相依赖么 spring与maven啥关系_jar_02


spring 两个项目maven可以互相依赖么 spring与maven啥关系_User_03


2. 配置pom文件

首先,我们得明确,一个最基本的Spring项目是什么

当然是Spring容器对对象的管理,通过反射创建对象,将对象纳入容器管理,并根据需要,注入我们的所需要的变量(实际上是让变量引用指向该对象的地址即可即可),而不用随时创建然后销毁,这个过程非常影响系统内存,一般来说,我们的Service层和Dao层需要这样的思想进行管理,只用创建一个单例对象,随用随取,这样这个对象也存在于我们的JVM内存模型的堆内存的老年代中,优化了整体性能

然后我们就得看看,有关对象的创建和管理都有哪些Jar包

1.spring-core.jar

这个jar 文件包含Spring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
外部依赖Commons-Logging, Log4J。

2.spring-beans.jar

这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
外部依赖spring-core,cglib-nodep.jar。

3.spring-context.jar

这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。

外部依赖spring-core.jar,spring-beans.jar,spring-aop.jar,commons-collections.jar,aopalliance.jar。

这么一来很明显,我们只需要引用spring-context.jar就行,因为他的外部依赖基本都全了不是么

<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.rxl</groupId>
	<artifactId>count</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>

		<java.version>1.8</java.version>

	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>4.0.4.RELEASE</version>
		</dependency>


	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
XML方式配置Spring

首先,建立我们的applicationContext.xml 在我们的src/mian/resources中,名字是约定俗成的,意思是应用上下文,你随便取一个名字也行,只要后面文件你能对的上号

spring 两个项目maven可以互相依赖么 spring与maven啥关系_java_04

<?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">


</beans>

接着,我们建一个实体类,用来测试对象的创建和存续

spring 两个项目maven可以互相依赖么 spring与maven啥关系_java_05

package pojo;

public class User {
	private String UserName;
	private String UserPassword;
	static int id = 1;
	private int MyId;

	public int getMyId() {
		return MyId;
	}

	public void setMyId(int myId) {
		MyId = myId;
	}

	public String getUserName() {
		return UserName;
	}

	public void setUserName(String userName) {
		UserName = userName;
	}

	public String getUserPassword() {
		return UserPassword;
	}

	public void setUserPassword(String userPassword) {
		UserPassword = userPassword;
	}

	public void create() {
		this.MyId = id;
		System.out.println("User " + MyId + " 被创建了");
		id++;
	}

	public void destroy() {
		System.out.println("User " + MyId + " 被销毁了");
	}
	@Override
	public String toString() {
		return "User [UserName=" + UserName + ", UserPassword=" + UserPassword + ", MyId=" + MyId + "]";
	}
}

向我们的applicationContext.xml 中添加bean的相关信息

<bean class="pojo.User" name="User" ></bean>

创建一个测试类,测试Spring 运行情况

package test;

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

import pojo.User;

public class Test {
   public static void main(String[] args) {
	   //获取上下文信息
	   AbstractApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
	   //根据name 反射class得到对象
	   User user = (User) ac.getBean("User");
	   user.setUserName("饶溪廉");
	   user.setUserPassword("饶溪廉很帅!");
	   System.out.println(user);
	   
	   User user2 = (User) ac.getBean("User");
	   System.out.println(user2);
}
}

运行结果:
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=0]
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=0]
可以看出,我们的对象只创建了一次,当我们再次需要这个对象时仅仅只是再次引用即可,而不是再次创建,这就是单例

那么如果我们需要多例的时候如何处理呢?
只需要改一下配置即可

<!-- 
name如果不指定,Spring 默认为 user(第一个字母小写)  
scope : singleton 单例,一般用于 Service Dao 层,运行期间只创建一个实例 (默认单例)
        prototype 多例,一般用于 Controller 层,用户每次访问就创建一个实例
        request 一次请求中创建一次
        session 一次会话中创建一次
-->
<bean class="pojo.User" name="User" scope="prototype"></bean>

再次运行测试代码
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=0]
User [UserName=null, UserPassword=null, MyId=0]

可以看到每次取出的对象都是新创建的

扩展:
init-method:对象创建时会执行的方法
destroy-method:对象销毁时会执行的方法

<bean class="pojo.User" name="User" scope="prototype" init-method="create" destroy-method="destroy"></bean>

再次运行上面的测试代码可以得到

User 1 被创建了
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=1]
User 2 被创建了
User [UserName=null, UserPassword=null, MyId=2]

不过很奇怪的是,并没有得到销毁的信息

因为,
单例模式中,对象是在spring容器创建之后直接被创建,纳入spring容器管理
多例模式中,对象是在每次需要时被创建,不纳入spring容器管理
单例模式中的对象的销毁是伴随着spring容器的销毁,
多例模式中的对象的销毁是被垃圾回收器给回收,
现在我们将User改为单例,在测试代码的末端将容器关闭

ac.close();

运行结果
User 1 被创建了
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=1]
User [UserName=饶溪廉, UserPassword=饶溪廉很帅!, MyId=1]
三月 06, 2020 2:03:06 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@49097b5d: startup date [Fri Mar 06 14:03:05 CST 2020]; root of context hierarchy
User 1 被销毁了

引申思考:Spring容器的创建顺序是如何执行的呢?
可参考文章

Spring核心 ApplicationContext的加载过程

我这里只简单的说一句,容器搭建完之后,先执行无参的构造方法,再执行init-method,至于单例和多例的区别看我上面写的,对象创建过程的顺序是一样的

链接:XML版本的源码 提取码:8o98

注解方式开发

  1. 构建Spring容器时启用包扫描功能,将指定包中的注解扫描解析,完成Spring容器的初始化
    因为要用到<context 上下文系列 的标签,所以需要加入引入和相应的规范
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation +
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd

<context:component-scan base-package=“pojo”></context:component-scan>

添加相应的注解,对应之前的标签

spring 两个项目maven可以互相依赖么 spring与maven啥关系_jar_06


spring 两个项目maven可以互相依赖么 spring与maven啥关系_jar_07


运行之前的代码

运行结果一样也可以直接在Test.java上直接注解扫描包等

spring 两个项目maven可以互相依赖么 spring与maven啥关系_java_08


spring 容器的创建方式变成

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Test.class);

运行结果也一摸一样

注解版本源码:
链接:https://pan.baidu.com/s/1bHJ8cigis42Z2dQCh57fNw
提取码:96lq