什么是Spring?
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
使用Spring 我们能做什么?
- 低侵入式设计,代码污染极低
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
- Spring的DI机制降低了业务对象替换的复杂性,提高了组件之间的解耦
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
- Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问
- Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
下载Spring 框架: https://repo.spring.io/release/org/springframework/spring/
需要配合 commons-logging-1.2.jar
包使用
如果使用eclips 开发 需要 在eclips 插件市场中搜索 spring 开发工具插件安装使用
核心结构
- 核心容器:核心容器提供 Spring 框架的基本功能(Spring Core)。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring 上下文:Spring 上下文是一个配置文件,向 Spring框架提供上下文信息。Spring 上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Bean 模块提供 BeanFactory,它是一个工厂模式的复杂实现。
第一行代码
首先创建一个 规范的 javaBean 类 名字 我们称为 Person
然后在工程src下创建applicationContext.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"
xmlns:p="http://www.springframework.org/schema/p"
>
<!-- 让spring 帮我们管理Person类对象 这个对象的名字叫 person
class 全类名 要被管理的类的名字
name 被管理对象的名称
-->
<bean class="com.lanou.Person" name="person">
<!-- value 用于注入基础数据类型
ref 用于注入引用数据类型-->
<property name="name" value="james"></property>
<property name="age" value="19"></property>
</bean>
</beans>
创建一个普通的java 类
public class HelloSpring {
public static void main(String[] args) {
// 想要从容器总获取被管理的对象
// 1. 创建容器
// classpath: 相当于src 路径下
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
// 2. 从容器中获取bean
Person p = (Person) ac.getBean("person");
System.out.println(p);
}
}
// 至此第一行代码书写完毕 以上我们使用了 set 注入方式 获得Person 类
// 下面我们介绍Spring 创建bean类对象的三种方式 和 四种注入方式
Bean对象的创建方式
1. 构造函数创建 (默认的)
2. 静态工厂创建 (调用指定的静态方法获取bean)
3. 实例工厂创建 (调用示例方法获取bean)
在spring 配置bean 时 如果不做别的操作 默认使用构造方法创建
静态工厂创建 是调用 自己写的工厂方法中的静态方法返回一个实例化对象
首先 我们创建一个名为PersonFactory 的类
public class PersonFactory {
// 静态工厂 方式创建bean (当我们希望自己创建对象时 使用)
public static Person getPerson() {
System.out.println("静态工厂方法 启动!");
return new Person();
}
public Person getPerson2() {
System.out.println("实例工厂方法 启动!");
return new Person();
}
}
配置文件中 我们这样定义
<bean name="person2" class="com.lanou.PersonFactory" factory-method="getPerson">
<property name="name" value="Tom"></property>
</bean>
非静态方法实例化对象 和静态方法实例化对象很相似
<bean name="person3" class="com.lanou.PersonFactory" factory-method="getPerson2" factory-bean="PersonFactory">
<property name="name" value="Miku"></property>
</bean>
三种注入
1. set 注入 (通过set方法 所有必须有set方法)
2. 构造函数注入
3. <:p 命名空间
4. SPEL表达式
第一种通过set 方式的注入 在第一行代码中已经演示
构造函数注入
<!-- 构造函数注入 调用指定的构造函数并传入参数实现注入
name 指定参数名 需要与构造函数一致
index 指定参数 放在哪一个位置 当多个构造函数参数类型相同时 但顺序不同时
使用index 进行区分
type 指定参数类型 当多个构造函数的参数顺序相同 但是数据类型不同时 使用
-->
<bean name="person4" class="com.lanou.Person">
<constructor-arg name="name" value="james" ></constructor-arg>
<constructor-arg name="age" value="19"></constructor-arg>
<constructor-arg name="car" ref="car"></constructor-arg>
</bean>
p 命名空间注入
<!-- p命名空间
需要先引入命名空间 xmlns:p="http://www.springframework.org/schema/p"
-->
<bean name="person5" class="com.lanou.Person" p:name="Make" p:age="20" p:car-ref="car"></bean>
SpEL 注入
<!-- SpEL 注入
Spring 的表达式语言 能实现简单的逻辑 与JSP EL表达式 一个性质
#{person.name } 找到一个 person对象 调用 getName 方法
-->
<bean name="person6" class="com.lanou.Person">
<property name="name" value="#{person.name }"></property>
<property name="age" value="#{person5.age }"></property>
<property name="car" ref="car"></property>
</bean>
在我们工作中 会遇到一些集合 数组等待类型的属性 这些该如何使用spring 注入呢?
首先创建一个bean 类型
声明:
private Object[] array;
private List list;
private Map map;
private Properties properties;
<bean id="collection" class="com.lanou.CollectionBean" >
<!-- 当元素只有一个时 直接使用value注入 -->
<property name="array" >
<array>
<value>james</value>
<value>Tom</value>
<value>Miku</value>
</array>
</property>
<!--注入list集合 也是value标签-->
<property name="list">
<list>
<value>Tomuya</value>
<value>Tama</value>
</list>
</property>
<!-- map中使用 entry 标签来指定键值对
如果key 或者 value是一个引用类型 就加上 -ref
-->
<property name="map">
<map>
<entry key="name" value="Nagisa"></entry>
<entry key="age" value="19"></entry>
<!-- <entry key="CLANNAD" value-ref="abean"></entry> -->
</map>
</property>
<property name="properties">
<props>
<prop key="name">misuha</prop>
<prop key="age">19</prop>
</props>
</property>
</bean>