一、Spring 框架整体功能
1. Core Container 核心容器
- Beans 和 Core 模块是框架的基础部分。
- Beans 模块提供 控制反转(IOC,Inversion of control) 和 依赖注入(DI,Dependency Injection) 特性。
- 这里的基础概念是 BeanFactory。
它提供对 Factory 模式 的经典实现,来消除对程序性 单例模式 的需要。
并真正地允许你从程序逻辑中,分离出 依赖关系和配置。
1.1 Beans 模块
- BeanFacotry 的作用。
- 它包含 访问配置文件、创建和管理 Bean,以及进行 IOC、DI 操作 相关的所有类。
1.2 Core 模块
- 主要包含 Spring 框架基本的核心工具类。
- Spring 的其他组件都要用到这个包里的类,Core 模块是其他组件的基本核心。
1.3 Context 模块
- 处理 BeanFactory,主要还是 ApplicationContext 的作用。
- 建于 Beans 和 Core 模块基础之上,提供了一种类似 JNDI 注册器 的框架式的对象访问方法。
- Context 模块继承了 Beans 的特性,为 Spring 核心提供了大量扩展,添加了对 国际化(例如: 资源绑定)、事件传播、资源加载 和 对 Context 的透明创建 的支持。
- Context 模块同时也支持 J2EE 的一些特性,ApplicationContext 接口是 Context 模块 的关键。
- 本质区别:使用 BeanFacotry 的 Bean 是延时加载的,ApplicationContext 是非延时加载的。
1.4 Expression Language 模块
- 提供了强大的表达式语言,用于在运行时查询和操纵对象。
- 它是 JSP-2.1规范 中定义的 Unifed expression language 的扩展。
- 该语言支持 设置获取属性的值、属性的分配,方法的调用、访问数组上下文(Accessiong the context of arrays)、容器和索引器、逻辑和算术运算符、命名变量。
- 它支持从 Spring 的 IOC 容器中根据名称检索对象。
- 它支持 List 投影、选择和一般的 List 聚合。
2. Data Access/Integration 数据访问/集成
2.1 JDBC 模块
- 提供了一个 JDBC 抽象层。
- 它可以消除冗长的 JDBC 编码 和 解析数据库厂商特有的错误代码。
- 这个模块包含了 Spring 对 JDBC 数据访问进行封装的所有类。
2.2 ORM 模块
- 它是流行的对象关系映射 API (如: JPA、JDO、Hibernate、iBatis 等),提供了 一个交互层。
- 利用 ORM 封装包,可以混合使用所有 Spring 提供的特性进行 O/R 映射,如下边提到的简单声明性事务管理。
2.3 OXM 模块
- 提供了一个对 Object/XML 映射实现的抽象层。
- Object/XML 映射实现包括 JAXB、Castor、XMLBeans、JiBX 和 XStrearn。
2.4 JMS 模块
- Java Messaging Service 消息服务。
- 主要包含了一些 制造 和 消费 消息的特性。
2.5 Transaction 事务
- 支持 编程 和 声明 式的事务管理。
- 这些事务类必须实现特定的接口,并且对所有的 POJO 都适用。
3. Web MVC
2.1 Web 模块
- 提供了基础的面向 Web 的集成特性(例如: 多文件上传、使用 Servlet listeners 初始化 IOC 容器,以及一个面向 Web 的应用上下文)。
- 它还包含 Spring 远程支持中 Web 的相关部分。
4. Aop 切面
4.1 Aspects 模块
- 提供了对 AspectJ 的集成支持。
4.2 Instrumentation 模块
- 提供了 Class instrumentation 支持 和 Classloader 实现,使得可以在特定的应用服务器上使用。
5. Test 测试
- 支持使用 JUnit 和 TestNG 对 Spring 组件进行测试。
二、Spring 容器类图
三、控制反转 和 依赖注入
1. 什么是控制反转?
要先了解软件设计的一个重要思想:依赖倒置原则 (Dependency Inversion Principle)。
2. 什么是依赖倒置原则?
- 假设我们设计一辆汽车:先设计轮子,然后根据轮子大小设计底盘,接着根据底盘设计车身,最后根据车身设计好整个汽车。
- 这里就出现了一个 依赖关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。
- IOC 思想最核心的地方在于 (资源不由使用资源的双方管理,而由不使用资源的第三方管理) 这可以带来很多好处。
- 第一,资源集中管理,实现资源的可配置和易管理。
- 第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。
四、Spring IOC 容器底层注解使用
Xml配置 VS 注解配置
1. 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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="xmlPerson" class="com.qs.springannotation.xml_bean.Person">
<property name="name" value="xmlPerson"/>
</bean>
</beans>
- XmlBeanFactory
/**
* XmlBeanFactory
*/
@Test
public void test() {
// 1. 创建容器(传入`XML配置文件`)。
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("xml_beans.xml"));
// 2. 容器中获取`Bean`。
Object bean = xmlBeanFactory.getBean(Person.class);
// 3. 打印`Bean`。
System.out.println(bean);
/*
`com.qs.springannotation.xml_bean.Person`无参构造
`com.qs.springannotation.xml_bean.Person`.setName,`name = xmlPerson`
Person{name='xmlPerson'}
*/
}
- ClassPathXmlApplicationContext
/**
* ClassPathXmlApplicationContext
*/
@Test
public void test2() {
// 1. 创建容器(传入`XML配置文件`)。
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("xml_beans.xml");
// 2. 容器中获取`Bean`。
Object bean = applicationContext.getBean("xmlPerson");
// 3. 打印`Bean`。
System.out.println(bean);
/*
`com.qs.springannotation.xml_bean.Person`无参构造
`com.qs.springannotation.xml_bean.Person`.setName,`name = xmlPerson`
Person{name='xmlPerson'}
*/
applicationContext.close();
}
2. 注解配置
@Configuration
public class BeanConfig {
/**
* 注意:通过`@Bean`的形式使用,`bean`的默认名称是方法名。
* 若`@Bean(value="指定bean的名称")`,那么`bean`的名称是指定bean的名称。
*/
@Bean
public Person person() {
return new Person();
}
}
- AnnotationConfigApplicationContext
/**
* `AnnotationConfigApplicationContext`。
*/
@Test
public void test3() {
// 1. 创建容器(传入`配置类`)。
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
// 2. 容器中获取`Bean`。
Object bean = applicationContext.getBean("person");
// 3. 打印`Bean`。
System.out.println(bean);
/*
`com.qs.springannotation.xml_bean.Person`无参构造
Person{name='null'}
*/
applicationContext.close();
}
五、Aware
1. ApplicationContextAware
@Component
public class MyApplicationContextAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.printf("`%s`.setApplicationContext,`applicationContext = %s`", this.getClass().getName(), applicationContext).println();
this.applicationContext = applicationContext;
}
}
2. BeanNameAware
@Component
public class MyBeanNameAware implements BeanNameAware {
@Override
public void setBeanName(String name) {
System.out.printf("`%s`.setBeanName,`name = %s`", this.getClass().getName(), name).println();
}
}