Spring的概述
1.什么是Spring?
Spring:SE/EE开发的一站式框架。
一站式框架:有EE开发的每一层解决方案。
WEB层 :SpringMVC
Service层 :Spring的Bean管理,Spring声明式事务
DAO层 :Spring的Jdbc模板,Spring的ORM模块
2.为什么学习Spring,spring的好处?
3.Spring的版本
Spring3.x和Spring4.x
Spring的入门(IOC)
1.什么是IOC?
IOC: Inversion of Control(控制反转)。
控制反转:将对象的创建权反转给(交给)Spring。
2.下载Spring的开发包
官网:http://spring.io/
3.解压Spring的开发包
docs :Spring的开发规范和API
libs :Spring的开发的jar和源码
schema :Spring的配置文件的约束
4.创建web项目,引入jar包
5.创建接口和类
问题:
如果底层的实现切换了,需要修改源代码,能不能不修改程序源代码对程序进行扩展?
原始方式:在写一个UserDaoHibernateImpl
6.现在我们将实现类交给Spring管理,配置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">
<!-- Spring的入门的配置 -->
<!-- <bean id="userDao" class="com.wangshi.spring4.dao.UserDaoImpl"></bean> -->
<bean id="userDao" class="com.wangshi.spring4.dao.UserDaoHibernateImpl"></bean>
</beans>
7.编写测试类:
调用实现类的时候直接修改xml文件就可以了;
package com.wangshi.spring4;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.wangshi.spring4.dao.UserDao;
import com.wangshi.spring4.service.UserService;
import com.wangshi.spring4.service.UserServiceImpl;
/**
* @author wanghaichan
*spring的入门
*/
public class SpringDemo01 {
@Test
/**
* 传统方式的调用
*/
public void demo(){
UserService us = new UserServiceImpl();
us.save();
}
@Test
/**
* Spring的方式的调用
*/
public void demo02(){
//创建spring的工厂;
ApplicationContext applicationcontext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationcontext.getBean("userDao");
userDao.save();
}
}
IOC和DI(*****)
IOC:控制反转,将对象的创建权反转给了Spring。
DI:依赖注入,前提必须有IOC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来。
面向对象的时候
依赖
Class A{
}
Class B{
public void xxx(A a){
}
}
传统模式:
现在我们用spring管理且注入,运行spring的demo方法
<!-- Spring的入门的配置,把属性注入 -->
<bean id="userDao" class="com.wangshi.spring4.dao.UserDaoImpl">
<property name="name" value="等你啊"></property>
</bean>
继承:is a
Class A{
}
Class B extends A{
}
聚合:has a
Spring的工厂类
1.Spring工厂类的结构图
ApplicationContext继承BeanFactory。
BeanFactory :老版本的工厂类
BeanFactory:调用getBean的时候,才会生成类的实例.
ApplicationContext :新版本的工厂类
-
ApplicationContext:加载配置文件的时候,就会将Spring管理的类都实例化。
-
ApplicationContext有两个实现类
ClassPathXmlApplicationContext :加载类路径下的配置文件(项目src下) FileSystemXmlApplicationContext :加载文件系统下的配置文件(磁盘下面)
@Test
/**
* Spring的方式的调用
* 加载文件系统下的配置文件,D盘
*/
public void demo03(){
//创建spring的工厂;
ApplicationContext applicationcontext = new FileSystemXmlApplicationContext("D://applicationContext.xml");
UserDao userDao = (UserDao) applicationcontext.getBean("userDao");
userDao.save();
}
Spring的配置
1.XML的提示配置
Schema的配置
Bean的相关的配置
1.标签的id和name的配置
id :使用了约束中的唯一约束。里面不能出现特殊字符的。
name :没有使用约束中的唯一约束(理论上可以出现重复的,但是实际开发不能出现的)。里面可以出现特殊字符。
Spring和Struts1框架整合的时候
<bean name=”/user” class=””/>
2.Bean的生命周期的配置(了解)
- init-method :Bean被初始化的时候执行的方法
- destroy-method :Bean被销毁的时候执行的方法(Bean是单例创建,工厂关闭)
<bean id="custDao" class="com.wangshi.spring401.dao.CustomerDemoImpl" init-method="setup" destroy-method="destroy" />
package com.wangshi.spring401.dao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author wanghaichan
*spring的入门
*/
public class SpringDemo01 {
@Test
/**
* Spring的方式的调用
* Bean的生命周期
*/
public void demo01(){
//创建spring的工厂;
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerDao custDao = (CustomerDao) applicationContext.getBean("custDao");
custDao.save();
//它的工厂里面没有,所以要用他的类
applicationContext.close();
}
}
3.Bean的作用范围的配置(重点)
-
scope :Bean的作用范围
singleton :默认的,Spring会采用单例模式创建这个对象。 prototype :多例模式。(Struts2和Spring整合一定会用到) request :应用在web项目中,Spring创建这个类以后,将这个类存入到request范围中。 session :应用在web项目中,Spring创建这个类以后,将这个类存入到session范围中。 globalsession :应用在web项目中,必须在porlet环境下使用。但是如果没有这种环境,相对于session。
Spring的Bean管理(XML方式)
1.Spring的Bean的实例化方式(了解)
Bean已经都交给Spring管理,Spring创建这些类的时候,有几种方式:
- 无参构造方法的方式(默认)
package com.wangshi.demo3;
/**
* 无参数构造方法方式
* @author wanghaihcaun
*/
public class Bean1 {
public Bean1() {
super();
System.out.println("Bean1的无参数的构造方法执行了...");
}
}
编写配置:
<!-- 无参数构造方法 -->
<bean id="bean1" class="com.wangshi.demo3.Bean1"></bean>
@Test
/**
* 无参数构造方法
*/
public void demo1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
}
- 静态工厂实例化的方式
编写Bean2的静态工厂:
package com.wangshi.demo3;
/**
* Bean2的静态工厂
* @author wanghaichan
*
*/
public class Bean2Factory {
public static Bean2 createBean2(){
System.out.println("Bean2Factory中方法执行了...");
return new Bean2();
}
}
@Test
/**
* 静态工厂实例化
*/
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
System.out.println(bean2);
}
编写配置:
<!-- 静态工厂实例化的方式 -->
<bean id="bean2" class="com.wangshi.demo3.Bean2Factory" factory-method="createBean2"></bean>
- 实例工厂实例化的方式
Bean3的实例工厂
package com.wangshi.demo3;
/**
* Bean3的实例工厂
* @author wanghaichuan
*
*/
public class Bean3Factory {
public Bean3 createBean3(){
System.out.println("Bean3的实例工厂执行了...");
return new Bean3();
}
}
编写配置:
@Test
/**
* 实例工厂实例化
*/
public void demo3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
System.out.println(bean3);
}
<!-- 实例工厂实例化的方式 -->
<bean id="Bean3Factory" class="com.wangshi.demo3.Bean3Factory"></bean>
<bean id="bean3" factory-bean="Bean3Factory" factory-method="createBean3"></bean>
Spring的属性注入
- 构造方法的方式的属性注入
package com.wangshi.entity;
/**
* @author wanghaichaun
*实体类
*/
public class Car {
//名字和价格
private String name;
private Double price;
public Car() {
super();
// TODO Auto-generated constructor stub
}
public Car(String name, Double price) {
super();
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
实现:
/**
* 构造方法属性注入
*/
@Test
public void demo01(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) applicationContext.getBean("car");
System.out.println(car);
}
- Set方法的方式的属性注入
普通属性注入
package com.wangshi.entity;
public class Car2 {
//名字和价格
private String name;
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
set方式设置对象类型的属性 :
/**
* set方法属性注入
*/
@Test
public void demo02(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Car2 car2 = (Car2) applicationContext.getBean("car2");
System.out.println(car2);
}
package com.wangshi.entity;
/**
* @author wanghaichuan
*员工的实体类
*spring的属性注入对象方式
*/
public class Employee {
private String name;
private Car2 car2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Car2 getCar2() {
return car2;
}
public void setCar2(Car2 car2) {
this.car2 = car2;
}
@Override
public String toString() {
return "Employee [name=" + name + ", car2=" + car2 + "]";
}
}
<!-- set方式设置对象类型的属性 -->
<bean id="employee" class="com.wangshi.entity.Employee">
<!-- value:设置普通类型的值,ref:设置其他类的id或name; -->
<property name="name" value="名硕"/>
<property name="car2" ref="car2"/>
</bean>
applicationContext.xml的配置
<!-- 属性注入的方法 -->
<bean id="car" class="com.wangshi.entity.Car">
<constructor-arg name="name" value="宝马" />
<constructor-arg name="price" value="800000" />
</bean>
<!-- set注入的方法 -->
<bean id="car2" class="com.wangshi.entity.Car2">
<property name="name" value="大奔" />
<property name="price" value="100000" />
</bean>
<!-- set方式设置对象类型的属性 -->
<bean id="employee" class="com.wangshi.entity.Employee">
<!-- value:设置普通类型的值,ref:设置其他类的id或name; -->
<property name="name" value="名硕"/>
<property name="car2" ref="car2"/>
</bean>
P名称空间的属性注入(Spring2.5以后)
-
通过引入p名称空间完成属性的注入:
写法: 普通属性 p:属性名=”值” 对象属性 p:属性名-ref=”值”
-
P名称空间的引入:
-
使用p名称空间:
<!-- 改为p名称空间的方式 -->
<bean id="car2" class="com.wangshi.entity.Car2" p:name="极地撒晨报" p:price="300000"></bean>
<!-- p名称空间注入对象 -->
<bean id="employee" class="com.wangshi.entity.Employee" p:name="挖掘机" p:car2-ref="car2"></bean>
SpEL的属性注入(Spring3.0以后)
SpEL:Spring Expression Language,Spring的表达式语言。
语法:#{SpEL}
新建类
package com.wangshi.entity;
/**
* @author wanghaichaun
*引入属性注入值
*/
public class CarInfo {
private String name;
public String getName() {
return "陨石沙暴,雷霆月斩";
}
public Double calculatorPrive(){
return Math.random()*3000;
}
}
<!-- SpEL的属性注入 及引入属性注入值-->
<bean id="carInfo" class="com.wangshi.entity.CarInfo"></bean>
<bean id="car2" class="com.wangshi.entity.Car2" >
<property name="name" value="#{carInfo.name}"/>
<property name="price" value="#{carInfo.calculatorPrive()}"/>
</bean>
<!-- SpEL的属性注入对象 -->
<bean id="employee" class="com.wangshi.entity.Employee">
<property name="name" value="#{'猪猪'}"/>
<property name="car2" value="#{car2}"></property>
</bean>
集合类型属性注入(了解)
新建类
package com.wangshi.collecton;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author wanghaichaun
*属性集合的注入
*/
public class CollectionBean {
private String[] arrs;
private List<String> list;
private Set<String>set;
private Map<String,String> map;
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setList(List<String> list) {
this.list = list;
}
public void setArrs(String[] arrs) {
this.arrs = arrs;
}
@Override
public String toString() {
return "CollectionBean [arrs=" + Arrays.toString(arrs) + ", list=" + list + ", set=" + set + ", map=" + map
+ "]";
}
}
实现代码:
package com.wangshi.collecton;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author wanghaichaun
*集合类型属性注入(了解)
*/
public class SpringDemo {
@Test
public void demo(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext01.xml");
CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
System.out.println(collectionBean);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- spring的集合属性的注入======== -->
<!-- 注入数组类型 -->
<bean id="collectionBean" class="com.wangshi.collecton.CollectionBean">
<!-- 数组类型 -->
<property name="arrs">
<list>
<value>阿东</value>
<value>阿北</value>
<value>阿男</value>
</list>
</property>
<!-- 注入list集合 -->
<property name="list">
<list>
<value>更好</value>
<value>手动</value>
<value>地方</value>
</list>
</property>
<!-- 注入set集合 -->
<property name="set">
<set>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</set>
</property>
<!-- 注入Map集合 -->
<property name="map">
<map>
<entry key="aaa" value="111"/>
<entry key="bbb" value="222"/>
<entry key="ccc" value="333"/>
</map>
</property>
</bean>
</beans>
Spring的分模块开发的配置
- 在加载配置文件的时候,加载多个
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext01.xml");
- 在一个配置文件中引入多个配置文件
<!-- 在一个配置文件中引入多个配置文件 -->
<import resource="applicationContext01.xml"/>