Spring框架介绍
Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。Spring的核心是控制反转(IoC)和面向切面(AOP)。
Spring设计理念
Spring就是面向Bean的编程,Bean在Spring中才是真正的主角。
Spring解决了一个非常关键的问题,它可以让你把对象之间的依赖关系转而用配置文件来管理,也就是它的依赖注入机制。而这个注入关系由一个叫Ioc的容器管理,里面包含着被Bean包裹的对象。Spring正是通过把对包装在Bean中从而达到管理这些对象及做一系列额外操作的目的。
Spring骨骼架构
Spring总共有十几个组件,但核心组件只有三个:Core、Bean和Context,它们构建起了整个Spring的骨骼架构。
spring-core模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
spring-beans模块提供BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
context模块建立在由core和beans模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能。Context模块也支持JavaEE的功能,比如EJB、JMX和远程调用等。ApplicationContext接口是Context模块的焦点。spring-context-support提供了对第三方库集成到Spring上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
核心组件如何协同工作
Bean包装的是Object,Context就是要发现每个Bean之间的关系,为它们建立关系并维护好这种关系,所以对Context就是一个Bean关系的集合,也就是前面所说Ioc容器,一旦建立起这个Ioc容器,Spring就可以为你工作了。而Core就是发现、建立和维护每个Bean之间关系所需要的一系列工具。
代码实现
先从实例入门,再一步步深入
基于Spring5.0.6,JDK1.8
GitHub地址:https://github.com/The-ProgramLife/Demo/tree/master/Spring
第一个Spring应用
实现Spring核心功能之一IOC(控制反转)
新建一个Java Maven Project
在pom.xml引入Spring依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
新建Category持久类
package pojo;
import org.springframework.stereotype.Component;
public class Category {
private int id;
private String name = "category1";
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在src/main/java下新建applicationContext.xml配置文件
applicationContext.xml是Sping的核心配置文件
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 注解配置 -->
<bean name="c" class="pojo.Category">
<property name="name" value="Categpry1"></property>
</bean>
</beans>
在主类编写运行逻辑
与传统通过new关键字创建对象不同,Spring通过加载组件的方式获取对象,所以对象的生命周期由Spring管理。
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//反转控制(Inversion of Control)与依赖注入(Dependency Inject)
Category c = (Category) context.getBean("c");
System.out.println(c.getName());
}
}
Spring获取到Category对象并注入name属性,这就是反转控制与依赖注入。
Spring的ApplicationContext容器
ApplicationContext是Spring中较高级的容器,包含BeanFactory所有功能,最常被使用的ApplicationContext接口实现:
FileSystemXmlApplicationContext | 该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。 |
ClassPathXmlApplicationContext | 该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。 |
WebXmlApplicationContext | 该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。 |
Spring的Bean定义
Bean是由Spring IOC容器管理的的对象,在XML表单配置元数据创建。以上例子用了Bean的name与class属性,它们分别指的是唯一的Bean标识符和Bean类,下面是一些其他属性
Bean作用域
singleton | 单例模式,仅有一个实例,默认值 |
prototype | 每次调用都返回新实例 |
request | 每次Http请求都创建新实例,只适用于WebApplicationContext |
session | 不同Session使用不同Bean,只适用于WebApplicationContext |
global-session | 一般用于Portlet应用环境,只适用于WebApplicationContext |
Bean生命周期
Bean的生命周期由Spring控制,我们可以在它被初始化和销毁时执行方法,只需定义属性init-method和destroy-method并指定组件中的方法即可,为了确保bean被正常销毁并调用destroy方法,可以在主类中调用容器的registerShutdownHook方法
Bean后置处理器
Bean后置处理器使用BeanPostProcessor接口定义回调方法,实现Bean初始化之前与之后执行特定的方法
新建InitCategory类实现BeanPostProcessor接口
覆写postProcessBeforeInitialization方法和postProcessAfterInitialization方法
public class InitCategory implements BeanPostProcessor{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
if ("c".equals(beanName)) {
System.out.println("BeforeInitialization : " + beanName);
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
if ("c".equals(beanName)) {
System.out.println("AfterInitialization : " + beanName);
}
return bean;
}
}
在applicationContext配置Bean
<bean class="pojo.InitCategory"></bean>
Bean继承
Spring的Bean继承与Java继承无关,但概念一样。使用parent属性实现继承,子Bean定义继承父Bean的配置数据,根据需要可以重写或添加值
修改applicationContext.xml代码
添加parent属性
<bean name="c" class="pojo.Category" >
<property name="name" value="Categroy1"></property>
</bean>
<bean name="p" class="pojo.Product" parent="c">
<property name="category" ref="c"></property>
</bean>
你也可以在applicationContext.xml定义一个Bean模板供子Bean使用,它不需要实现类,但要指定abstract属性。
<bean id="beanTeamplate" abstract="true">
<property name="name" value="Category"/>
</bean>
<bean id="p" class="pojo.Product" parent="beanTeamplate">
</bean>