继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用!
7.自定义Spring框架
7.1 Spring框架使用回顾
7.1.1 数据访问层
定义UserDaoMapper接口及实现类
public interface UserMapper {
public void add();
}
public class UserMapperImpl implements UserMapper {
public void add(){
System.out.println("userMapperImpl....");
}
}
7.1.2 业务逻辑层
定义UserService接口及实现类
public interface UserService {
public void add();
}
public class UserServiceImpl implements UserService {
//声明userMapper对象
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public void add() {
System.out.println("UserService.............................");
userMapper.add();
}
}
7.1.3 控制层
定义Controller类简单实现
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.add();
}
7.1.4 applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userMapper" class="org.example.mapper.impl.UserMapperImpl"></bean>
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper"></property>
</bean></beans>
7.1.5 运行
结果如图
7.2 Spring核心功能结构
Spring约有20个模块,由1300多不同文件构成,主要分为:核心容器、AOP和设备支持、数据访问与集成、Web组件、通信报文和集成测试,结构图如下:
7.2.1 核心容器
核心容器由beans、core、context和expression(Spring Expression Language,SPEL)组成。
7.2.1.1 核心模块
spring-beans和spring-core模块。
包含:
- 控制反转(Inversion of Control),实际应用程序代码进行分离
- 依赖注入(Dependency Injection)
BeanFactory使用控制反转对应用程序的配置和依赖性规范Bean,只有当Bean被使用时,BeanFactory才会对该Bean进行实例化与依赖关系装配
7.2.1.2 spring-context模块
- 架构于核心模块纸上,扩展了BeanFactory,添加了Bean生命周期控制、框架事件体系及资源加载透明化等功能,还提供了企业级支持,如邮件访问,远程访问及任务调度等。核心接口为ApplicationContext,超类是BeanFactory。
- spring-context-support模块是对spring IOC容器及IOC子容器的扩展支持
- spring-context-index模块是Spring的类管理组件和Classpath扫描组件
7.2.1.3 spring-expression模块
- 统一表达式语言(EL )的扩展模块,可以查询、管理运行中的对象,也可以方便调用对象方法,操作数组、集合等。
- 语法类似于传统EL,但提供了额外的功能,如函数调用和简单字符串模板函数
- 特性是基于Spring产品的需求设计,可方便与Spring IOC进行交互。
7.2.2 bean描述
- Spring面向bean编程(BOP,Bean Oriented Programming),Bean在Spring中处于核心地位。
- Spring IOC容器通过配置文件或者注解的方法来管理bean对象之间的依赖关系
- bean用于对类进行封装,如:
<bean id = "userService" class = "com.demo.service.impl.userServiceImpl">
<property name = "useMapper" ref = "userMapper"/>
</bean>
<bean id = "userMapper" class = "com.demo.mapper.impl.userMapperImpl"/>
- Bean 重要性:
- spring将bean对象交由一个IOC容器管理
- bean对象之间依赖关系在配置文件中体现,由spring完成
7.3 Spring IOC接口分析
7.3.1 BeanFactory解析
Bean创建是工厂模式,一系列工厂即IOC容器,Spring中很多IOC容器实现供用户选择,一些接口相互关系如图:
- 接口阐述:BeanFactory作为最顶层接口,定义了IOC容器的基本功能规范,BeanFactory有三个重要子接口:ListableBeanfactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。但最终默认实现类是DefaultListableBeanFactory,实现了所有接口。
- 定义多层次接口原因:主要为了区分在Spring内部操作过程中对象传递和转化,对对象数据访问进行限制,例如:
- ListableBeanFactory接口表示这些Bean可列表化
- HierarchicalBeanFactory表示这些Bean是有继承关系
- AutowireCapableBeanFactory接口定义Bean的自动装配规则
上述三个接口共同定义了Bean集合、Bean 之间关系及Bean行为,最基本IOC容器接口是BeanFactory。
- BeanFactory里只对IOC容器基本行为进行定义,不关心Bean是如何定义及加载
- BeanFactory有一重要子接口:ApplicationContext,该接口主要来规范容器中的bean对象是非延迟加载,即在创建容器对象的时候就对象bean进行初始化并存储到一个容器中。
- 若要知道工厂如何产生对象,则需要看具体的IOC容器实现,如:
- ClasspathXmlApplicationContext:根据类路径加载xml配置文件,并创建IOC容器对象
- FileSystemXmlApplicationContext:根据系统路径加载xml配置文件,并创建IOC容器对象
- AnnotationConfigApplicationContext:加载注解类配置,并创建IOC容器
7.3.2 BeanDefination解析
Spring IOC容器管理定义的各种bean对象及相互关系,而Bean对象在Spring实现是以BeanDefinition来描述,如:
<bean id = "userMapper" class = "com.demo.mapper.impl.userMapperImpl"></bean>
%%bean标签还有很多属性,如scope、init-method、destory-method等%%
继承关系如图
7.3.3 BeanDefinationReader解析
Bean解析主要是对Spring配置文件解析,其过程主要通过BeanDefinitionReader来完成,Spring中BeanDefinitionReader类结构图如下图
BeanDefinintionReader接口源代码如下:
public interface BeanDefinitionReader {
//获取BeanDefinitionRegistry注册器对象
BeanDefinitionRegistry getRegistry();
@Nullable
ResourceLoader getResourceLoader();
@Nullable
ClassLoader getBeanClassLoader();
BeanNameGenerator getBeanNameGenerator();
//从指定资源里加载bean定义
int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException;
}
7.3.4 BeanDefinationRegistry解析
上文解析的bean对象存储到BeanDefinition的注册中心,而该注册中心顶层接口就是BeanDefinitionRegistry,源码如下:
public interface BeanDefinitionRegistry extends AliasRegistry {
//往注册表中注册bean
void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
//从注册表删掉指定名称bean
void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
//获取指定名称bean
BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
//判断是否包含指定名称bean
boolean containsBeanDefinition(String var1);
//获取所有bean
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String var1);
}
继承结构如图
类图可看出BeanDefinitionRegistry接口子实现类主要有:
- DefaultListableBeanFactory,该类定义如下代码来注册bean
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
- SimpleBeanDefinitionRegistry,该类定义如下代码来进行注册bean
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(64);
7.3.5 ClassPathXmlApplicationContext解析
ClassPathXmlApplicationContext对Bean配置资源载入是从refresh()方法开始,此方法是一个模板方法,规定IOC容器的启动流程,有些逻辑要交给其子类实现。对Bean配置资源进行载入。
ClassPathXMLApplicationContext通过调用其父类AbstractApplicationContext的refresh方法启动整个IOC容器对Bean定义的载入过程。