目录
1、Spring介绍
Spring是一个开放源代码胡设计层面框架,解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是2003年兴起的一个轻量级的java开发框架,由RodJohnson创建。简单来说,Spring是一个分层的javaSE/EE full-stack(一站式)轻量级开源框架。
1.1 spring特点
1)方便解耦,简化开发
通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2)AOP编程的支持
通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用于传统OOP实现的功能可以通过AOP轻松应付。
3)声明式事务的支持
在Spring中,可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
4)方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情,例如:Spring对junit4支持,可以通过注解方便的测试Spring程序。
5)方便继承各种优秀框架
Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hi贝尔马特、Hessian、Quartz)等的直接支持。
6)降低JavaEE API的使用难度
1.2 Spring组织架构
ORM - object relation mapping
OXM - Object xml mapping
JMS - Java消息服务(Java Message Service,JMS)
WebSocket protocol 是HTML5 一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。Socket是传输控制层协议,WebSocket是应用层协议。
Protlet是一种Web组件,就像servlet 是专为将合成页面里的内容聚集在一起而设计的。通常请求一个portal页面会引发多个portlets被调用。每个portlet都会生成标记段,并与别的portlets生成的标记段组合在一起嵌入到portal页面的标记内。
spring全家桶:spring、Spring Data、Spring MVC、Spring Boot、Spring Cloud(微服务)
1.3 Spring下载
Spring官网:http://spring.io
Spring资源地址:http://repo.spring.io/release/org/springframework/spring
1.4 Spring的核心模块
- spring-core:依赖注入IOC与DI的最基本实现
- spring-beans:Bean工厂与bean的装配
- spring-context:spring的context上下文即IOC容器
- spring-context-support
- spring-expression:spring表达式语言
2、spring中的IOC
IOC是Inverse of Control的简写,意思是控制反转,是降低对象之间的耦合关系的设计思想。
DI是Dependency Injection的缩写,意思是依赖注入,说的是创建对象实例时,同时为这个对象注入它所依赖的属性。
2.1 实现过程
步骤1:添加jar包
<!-- Spring的核心工具包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- 在基础IOC功能上提供扩展服务,还提供许多企业级服务的支持,有邮件服务、任务调度、远程访问、缓存以及多种视图层框架的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- Spring IOC的基础实现,包含访问配置文件、创建和管理bean等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- Spring context的扩展支持,用于MVC方面 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- spring表达式语言 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
步骤2:创建配置文件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">
</beans>
步骤3:在配置文件中创建对象
<bean id="对象名" class="类的完成路径">
<property name="属性名" ref="对象的id值"></property>
</bean>
步骤4:加载配置文件,获得对象
ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
Users users = (Users)app.getBean("u1");
2.2 bean标签的属性介绍
属性 | 说明 |
class | 指定bean对应类的全路径 |
name | name是bean对应对象的一个标识 |
scope | 执行bean对象创建模式和生命周期,scope="singleton"和scope="prototype" |
id | id是bean对象的唯一标识,不能添加特别字符 |
lazy-init | 是否延时加载,默认值:false。true延迟加载对象,当对象被调用的时候才会加载,测试的时候,通过getbean()方法获得对象。lazy-init="false"默认值,不延迟,无论对象是否被使用,都会立即创建对象,测试时只需要加载配置文件即可。注意:测试的时候只留下id,class属性 |
init-method | 只需要加载配置文件即可对象初始化方法 |
destroy-method | 对象销毁方法 |
2.3 对象创建的方式
(1)无参构造
(2)有参构造
public Person(String name,Car car){
this.name = name;
this.car = car;
System.out.println("Person的有参构造方法:"+name+car);
}
<bean name="Person" class="com.xzk.spring.bean.Person">
<constructor-arg name="name" value="rose"/>
<constructor-arg name="car" ref="car"/>
</bean>
(3)静态方法创建对象
// 静态工程模式
public class PersonFactory{
public static Person createPerson(){
System.out.println("静态工厂创建Person");
return new Person();
}
}
<bean name="pf" class="com.xzk.PersonFactory" factory-method="createPerson" />
(4)非静态工厂方法
public class Users{
public Person createPerson1(){
System.out.println("非静态工厂创建Person");
return new Person();
}
}
<bean id="u2" class="com.bean.Users"></bean>
<bean id="u3" factory-method="createPerson1" factory-bean="u2"></bean>
2.4 springBean的生命周期
Bean生命周期的整个执行过程描述如下:
1)根据配置情况调用Bean构造方法或工厂方法实例化Bean;
2)利用依赖注入完成Bean中所有属性值的配置注入;
3)如果Bean实现了BeanNameAware接口,则Spring调用Bean的serBeanName()方法传入当前Bean的id值;
4)如果Bean实现了BeanFactoryAware接口,则Spring调用setBeanFactory()方法传入当前工厂实例的引用;
5)如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicationContext()方法传入当前ApplicationContext实例的引用;
6)如果BeanPostProcessor和Bean关联,则Spring将调用该接口的预初始化postProcessBeforeInitialzation()对Bean进行加工操作,此处非常重要,Spring的AOP就是利用它实现的。
7)如果Bean实现了InitializingBean接口,则Spring将调用afterPropertiesSet()方法。初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet必须实现InitializingBean接口。实现InitializingBean接口必须实现afterPropertiesSet方法。
8)如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法。
9)如果BeanPostProcessor和Bean关联,则Spring将调用该初始化方法postProcessAfterInitialization()。此时,Bean已经可以被应用系统使用了。
10)如果指定了该Bean的作用范围为scope="singleton",则将该Bean放入Spring Ioc的缓存池中,将触发Spring对该Bean的生命周期管理;如果指定了该Bean的作用范围为scope="prototype",则将该Bean交给调用者,调用者管理该Bean的生命周期,Spring不再管理该Bean。
11)如果Bean实现了DisposableBean接口,则Spring会调用destory()方法将Spring中的Bean销毁如果在配置文件中通过destory-method属性指定了Bean的销毁方法,则Spring将调用该方法对Bean进行销毁。
3、DI注入值
分类:一种是调取属性的set方法赋值;第二种使用构造方法赋值;
3.1 set注入值
3.1.1 基本属性类型值注入
<property name="name" value="jeck"/>
3.1.2 引用属性类型值注入
<property name="car" ref="car"></property>
3.2 构造注入
3.2.1 可以通过name属性,按照参数名赋值
public Person(String name,Car car){
this.name = name;
this.car = car;
System.out.println("Person的有参构造方法:"+name+car);
}
<bean name="person" class="com.xzk.spring.bean.Person">
<constructor-arg name="name" value="rose"/>
<constructor-arg name="car" ref="car"/>
</bean>
3.2.2 可以通过index属性,按照参数索引注入
<bean name="person2" class="com.xzk.spring.bean.Person">
<constructor-arg name="name" value="helen" index="0"></constructor-arg>
<constructor-arg name="car" ref="car" index="1"></constructor-arg>
</bean>
3.2.3 使用type注入
public Person(Car car, String name) {
super();
System.out.println("Person(Car car, String name)");
this.name = name;
this.car = car;
}
public Person(Car car, Integer name) {
super();
System.out.println("Person(Car car, Integer name)");
this.name = name + "";
this.car = car;
}
<bean name="person2" class="com.xzk.spring.bean.Person">
<constructor-arg name="name" value="988" type="java.lang.Integer"></constructor-arg>
<constructor-arg name="car" ref="car" ></constructor-arg>
</bean>
3.3 spel spring表达式
<bean name="car" class="com.xzk.spring.bean.Car" >
<property name="name" value="mime" />
<property name="color" value="白色"/>
</bean>
<!--利用spel引入car的属性 -->
<bean name="person1" class="com.xzk.spring.bean.Person" p:car-ref="car">
<property name="name" value="#{car.name}"/>
<property name="age" value="#{person.age}"/>
</bean>
3.4 p命名空间注入值
使用p:属性名 完成注入,走set方法
- 基本类型值:p:属性名="值"
- 引用类型值:P:属性名-ref="bean名称"
实现步骤:配置文件中,添加命名空间p
xmls:p="http://www.springframework.org/schema/p"
实例:
<bean id="u6" class="com.entity.Users" p:age="30" p:name="李四" p:student-ref="stu1"></bean>
3.5 复杂类型注入
Object[],list,set,map,java.util.Properties
<!-- 数组变量注入 -->
<property name="arrs">
<list>
<value>数组1</value>
<!--引入其他类型-->
<ref bean="car"/>
</list>
</property>
<!-- 集合变量赋值-->
<property name="list">
<list>
<value>集合1</value>
<!--集合变量内部包含集合-->
<list>
<value>集合中的集合1</value>
<value>集合中的集合2</value>
<value>集合中的集合3</value>
</list>
<ref bean="car" />
</list>
</property>
<!--map赋值 -->
<property name="map">
<map>
<entry key="car" value-ref="car" />
<entry key="name" value="保时捷" />
<entry key="age" value="11"/>
</map>
</property>
<!-- properties赋值 -->
<property name="properties">
<props>
<prop key="name">pro1</prop>
<prop key="age">111</prop>
</props>
</property>
3.6 自动注入 (由程序自动给属性赋值)
autowire:
no 不自动装配(默认值)
byName 属性名=id名,调取set方法赋值
byType 属性的类型和id对象的类型相同,当找到多个同类型的对象时报错,调取set方法赋值
constructor 构造方法的参数类型和id对象的类型相同,当没有找到时,报错。调取构造方法赋值
示例:
<bean id="service" class="service.impl.UserServiceImpl" autowire="constructor"> </bean>
配置全局自动装配:
<beans default-autowire="constructor/byName/byType/no">