spring概述
重要部分
Spring是一个容器,用来管理java对象的创建以及其他功能的扩展,目前java的生态已经离不开spring,所以spring在java领域是一个极其重要的框架,在spring的思想中IOC(控制反转)和AOP(切面编程)是重要部分,而实现控制反转包含属性注入,也叫依赖注入DI(依赖注入)
官网架构图
Test 模块:
- Spring 支持 Junit 和 TestNG 测试框架,而且还额外提供了一些基于 Spring 的测试功能
Data Access/Integration:
- 数据访问和集成,提供jdbc、orm等框架的API
Core Container(Spring 的核心容器):
- Beans 模块:提供了框架的基础部分,包括控制反转和依赖注入。
- Core 核心模块:封装了 Spring 框架的底层部分,包括资源访问、类型转换及一些常用工具类。
- Context 上下文模块:建立在 Core 和 Beans 模块的基础之上,集成 Beans 模块功能并添加资源绑定、数据验证、国际化、Java EE 支持、容器生命周期、事件传播等。ApplicationContext 接口是上下文模块的焦点
- SpEL 模块:提供了强大的表达式语言支持,支持访问和修改属性值等
AOP、Aspects、Instrumentation 和 Messaging:
- AOP 模块:提供了面向切面编程实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中,这样各司其职,降低业务逻辑和通用功能的耦合
- Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架
- Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用
- messaging 模块:Spring 4.0 以后新增了消息(Spring-messaging)模块,该模块提供了对消息传递体系结构和协议的支持
Web 模块:
- Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IOC 容器初始化以及 Web 应用上下文。
- Servlet 模块:提供了一个 Spring MVC Web 框架实现。Spring MVC 框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的 JSP 标签,完全无缝与 Spring 其他技术协作。
- WebSocket 模块:提供了简单的接口,用户只要实现响应的接口就可以快速的搭建 WebSocket Server,从而实现双向通讯。
- Portlet 模块:提供了在 Portlet 环境中使用 MVC 实现,类似 Web-Servlet 模块的功能。
开发环境准备
创建maven空项目引入spring依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.0.RELEASE</version></dependency>
创建测试java文件
package com.tech.test.service;public interface UserService {public void getUser();
}
package com.tech.test.service.impl;import com.tech.test.service.UserService;
import org.springframework.beans.factory.InitializingBean;public class UserServiceImpl implements UserService, InitializingBean {@Overridepublic void getUser() {System.out.println("get User Success");}/*** Bean初始化方法*/public void init(){System.out.println("初始化方法");}/*** Bean销毁前方法*/public void destroy(){System.out.println("销毁前方法");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("initBean...");}
}
添加spring配置文件application.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"></beans>
BeanFactory
BeanFactory 是早期的spring Bean工厂,是一个容器的顶层接口,在applicationContext容器中最重要的部分也是BeanFactory,只不过是封装了BeanFactory之后有扩展了其他功能,常用工厂实现类是DefaultListableBeanFactory
BeanFactory获取bean
<bean id="userService" class="com.tech.test.service.impl.UserServiceImpl"></bean>
package com.tech.test.springtest;import com.tech.test.service.UserService;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;public class TestBeanFactory {public static void main(String[] args) {// 创建BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 创建读取器 读取xmlXmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// 读取配置文件交给工厂xmlBeanDefinitionReader.loadBeanDefinitions("applicationContext.xml");// 从工厂通过名称获取bean实例 UserService userService = (UserService)beanFactory.getBean("userService");// 从工厂通过类型获取bean实例 byType 必须保证单例唯一 不用强转// UserService userService = beanFactory.getBean(UserService.class);// 使用方法userService.getUser();}}
测试结果
配置的id最后会转变成name,存在singletonObjects中,也叫单例池和一级缓存(后面介绍)
ApplicationContext
ApplicationContext被称为spring容器,内部封装了BeanFactory,但比BeanFactory更加强大,提供了事件发布、资源解析,消息资源,国际化等,但ApplicationContext的核心功能还是BeanFactory
ApplicationContext继承体系
常用的有三个具体实现类作为容器
ClassPathXmlApplicationContext :加载类路径下的xml配置的ApplicationContext
FileSystemXmlApplicationContext :加载系统磁盘下的xml配置的ApplicationContext
AnnotationConfigApplicationContext :加载注解配置类的ApplicationContext
当前只在单spring的环境下继承体系如上图所示,但加入了web依赖,继承体系会发生变化
<dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.3.7</version>
</dependency>
继承体系如下
ApplicationContext获取Bean
上述BeanFActory的applicationContext.xml的Bean配置不变
package com.tech.test.springtest;import com.tech.test.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestApplicationContext {public static void main(String[] args) {// 加载容器ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取BeanUserService userService = (UserService) classPathXmlApplicationContext.getBean("userService");// 使用方法userService.getUser();}
}
测试结果
与BeanFactory的效果一致,配置的id最后会转变成name,存在singletonObjects中,也叫单例池和一级缓存(后面介绍)
BeanFactory和ApplicationContext的区别
BeanFactory加载Bean是懒加载,在getBean的时候才回去创建Bean,Application是容器创建就实例化好所有的bean,通过断点可验证
ApplicationContext内部封装了BeanFactory,并且比BeanFactory更强大