Spring框架概述
Spring 是一个轻量级的 DI/IoC 和 AOP 容器的开源框架,致力于构建轻量级的 JavaEE 应用.
容器
容器还要管理对象的生命周期,如 Tomcat 就是 Servlet 和 JSP 的容器
架构
1.Core Container(核心容器)包含有 Beans、Core、Context 和 SpEL 模块。
2.Data Access/Integration 层包含有 JDBC、ORM、OXM、
3.JMS 和 Transactions 模块。
4.Web 层包含了 Web、Servlet、WebSocket、Porlet 模块。
5.AOP 模块提供了遵循 AOP 联盟标准的面向切面编程的实现。
6.Test 模块支持使用 JUnit 和 TestNG 对 Spring 组件进行测试。
IoC和DI思想
IoC:Inversion of Control(反转控制)
将原本在程序中手动创建对象的控制权,交由 Spring 框架的 IoC 容器来管理.调用者只管负责从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也不关心该对象依赖对象的创建以及依赖关系的组装,也就是把创建对象的控制权反转给了 Spring 框架.
IoC_Demo
domain:1
2
3
4
5
6
7
8
9
10
11
12public class HelloWorld {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void sayHello() {
System.out.println(name + "你好,年龄" + age); }
}
XML 配置:1
2
3
4
5
6
7
8
9
10
<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="helloWorld" class="...HelloWorld">
<property name="name" value="will"/> 对应HelloWorld中的setName方法
<property name="age" value="17" /> 对应 HelloWorld 中的 setAge 方法
</bean>
</beans>
测试类:1
2
3
4
5
6
7
8HelloWorld world = null;
//加载 Spring 配置文件 applicationContext.xml
Resource resource = new ClassPathResource("applicationContext.xml");
//创建 Spring 容器对象
BeanFactory factory = new XmlBeanFactory(resource);
//从 Spring 容器中获取制定名为 helloWorld 的 bean
world = (HelloWorld) factory.getBean("helloWorld");
world.sayHello();
BeanFactory
Spring IoC 容器——生产 bean 对象的工厂,负责配置,创建和管理 bean.
被 Spring IoC 容器管理的对象称之为 bean
Spring IoC 管理 bean 的原理:
1.通过 Resource 对象加载配置文件
2.解析配置文件,得到指定名称的 bean
3.解析 bean 元素,id 作为 bean 的名字,class 用于反射得到 bean 的实例:注意:此时,bean 类必须存在一个无参数构造器(反射创建:和访问权限无关);
4.调用 getBean 方法的时候,从容器中返回对象实例;
就是把代码从 JAVA 文件中转移到了 XML 中1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19HelloWorld wolrd = null;
String className="...HelloWorld";
//-----------------------------------------------------
Class clz = Class.forName(className);
Constructor con = clz.getDeclaredConstructor();
con.setAccessible(true);
wolrd = (HelloWorld)con.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(wolrd.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
String propertyName = pd.getName();
Method setterMethod =pd.getWriteMethod();
if("name".equals(propertyName)){
setterMethod.invoke(wolrd, "Will");
}else if("age".equals(propertyName)) {
setterMethod.invoke(wolrd, 17);
} }
//-----------------------------------------------------
wolrd.sayHello();
getBean 方法签名
方式一:按照 bean 的名字拿 bean,按照名字拿 bean 不太安全1
world = (HelloWorld) factory.getBean("helloWorld");
方式二:按照类型拿 bean,要求在 Spring 中只配置一个这种类型的实例1
world = factory.getBea (HelloWorld.class);
方式三:按照名字+类型(推荐)1
world = factory.getBean("helloWorld",HelloWorld.class);
bean元素id,name和import
id:可以使用字母、数字、连字符、下划线、句话、冒号,不能以“/”开头(spring3.1之前)
name:使用 name 属性为 bean 元素起多个别名,多个别名之间使用逗号或空格隔开.
import resource:将一个
applicationContext.xml 文件分解成多个配置文件,然后在 applicationContext.xml 文件中包含其他配置文件1
<import resource="classpath:路径1/路径2/hello.xml"/>
Spring 测试框架
基于 JUnit4 的测试:1
2
3
4
5
6
7
8
9
10
11
12
13 (SpringJUnit4ClassRunner.class)
"classpath:springTest.xml") (
public class SpringTestTest {
private HelloWorld world;
public void test1() throws Exception {
world.sayHello();
}
}
@ContextConfiguration
默认去找的当前测试类名-context.xml 配置文件,如:SpringTestTest-context.xml
IoC 容器
BeanFactory:
Spring 最底层的接口,只提供了的 IoC 功能,负责创建、组装、管理 bean,在应用中一般不使用 BeanFactory
ApplicationContext:
ApplicationContext 接口继承了BeanFactory,除此之外还提供 AOP 集成、国际化处理、事件传播、统 一资源价值等功能.
bean实例化方式
2.静态工厂方法实例化:解决系统遗留问题
3.实例工厂方法实例化:解决系统遗留问题
必须保证 SomeBean1 必须有无参数构造器,和访问权限无关
1.构造器实例化(无参数构造器),最标准,使用最多.1
2
3
4
5public class SomeBean1 {
public SomeBean1() {
System.out.println("SomeBean1 构造器"); }
}
<bean id="someBean1" class="...SomeBean1"/>
4.实现 FactoryBean 接口实例化:实例工厂变种
用于其他框架和 Spring 集成,如集成 MyBatis 使用:org.mybatis.spring.SqlSessionFactoryBean1
2
3
4
5
6
7
8
9
10
11public class SomeBean4 {
}
public class SomeBean4FactoryBean implements FactoryBean<SomeBean4>{
public SomeBean4 getObject() throws Exception {
//TODO
return new SomeBean4();
}
public Class<?> getObjectType() {
return SomeBean4.class;
} }
<bean id="someBean4" class="...SomeBean4FactoryBean"/>
Bean 作用域
1 | <bean id="" class="" scope="作用域"/> |
singleton: 单例
prototype: 多例,每次从容器中调用 Bean 时,都返回一个新的实例
Bean 初始化和销毁
1.init-method:bean 生命周期初始化方法,bean 对象创建后就进行调用.
2.destroy-method:容器被正常销毁的时候,如果 bean 被容器管理,会调用该方法.
DI 核心
1.所谓注入,可以简单理解为 IoC 容器创建对象的时候,设置相关的属性值.
2.给对象设置数据:
要么是在创建对象的时候通过构造器传入.
要么就是先创建对象,再通过setter 方法再设置
所以,注入方式主要有两种:
1.setter 方法注入
1 | //注入常量 |
2.构造器注入:
构造器方式注入使用:1
2
3
4
5
6
7<constructor-arg/>元素
//安装构造器的参数名字设置值
<constructor-arg name="name" value="will"/>
<constructor-arg name="age" value="17" />
<constructor-arg name="other" ref="otherBean"/>
<constructor-arg name="prop">
配置连接池
1 | <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" |
抽取 db.properties 文件1
2
3
4
5jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///springdemo
jdbc.username=root
jdbc.password=admin
jdbc.initialSize=5