Spring精讲(一)

 

目录

 

一.了解Spring

二.Spring入门

2.1 Spring开发包

2.2 创建项目引入jar包

三.IOC&DI

3.1 IOC

3.1.1 IOC的主题引入

3.1.2 IOC解决上述问题

3.2 DI

四.Spring工厂类

4.1 工厂类结构图

4.2 BeanFactory (老版本的工厂类)

4.3 ApplicationContext (新版本的工厂类)

五.Spring的配置

5.1 Schema本地的配置

5.2 Bean的相关配置

5.2.1  标签的id和name的配置

5.2.2 Bean的生命周期的配置

5.2.3 Bean的作用范围的配置(重点)

六.Spring中bean的管理(XML)

6.1 Spring中Bean的实例化方式

6.1.1 无参构造方法的方式(默认)

6.1.2 静态工厂实例化的方式

6.1.3 实例工厂实例化的方式

6.2 Spring的属性注入

6.2.1 构造方法的方式的属性注入

6.2.2 set方法的方式的属性注入

6.2.3 set方法设置对象类型的属性

6.2.4 P名称空间的属性注入(Spring2.5以后)

6.2.5 SpEL的属性注入(Spring3.0以后)

6.2.6 集合类型属性注入

 七.Spring分模块开发与项目优化

7.1 引入配置文件

7.2 Spring项目优化

7.2.1 问题:

7.2.2 解决方案:


一.了解Spring

  • Spring:SE/EE开发的一站式框架(有EE开发的每一层解决方案)
    • WEB层            :SpringMVC
    • Service层        :Spring的Bean管理,Spring声明式事务
    • DAO层             :Spring的Jdbc模板,Spring的ORM模块

功能: 

二.Spring入门

2.1 Spring开发包

  • docs          :Spring的开发规范和API
  • libs             :Spring的开发的jar和源码
  • schema     :Spring的配置文件的约束

2.2 创建项目引入jar包

在 Sping开发包中找到以下jar包并引入项目

三.IOC&DI

3.1 IOC

IOC: Inversion of Control(控制反转)。

控制反转:将对象的创建权反转给(交给)Spring。

3.1.1 IOC的主题引入

以往我们在项目中处理dao层通常用下面这种方式

/**
 * 用户管理DAO层接口
 *
 */
public interface UserDAO {
	public void save();
}
/**
 * 用户管理DAO层实现类
 *
 */
public class UserDAOImpl implements UserDAO {

	@Override
	public void save() {
		System.out.println("UserDAOImpl执行了...");
	}

}
	/**
	 * 传统方式的调用
	 */
	public void demo1(){
		UserDAOImpl userDAO = new UserDAOImpl();
		userDAO.save();
	}

问题:

如果底层的实现切换了,需要修改源代码,比如说原本对数据库的操作用的是JDBC,现在要切换成Hibernate,是否可以不修改程序源代码对程序进行扩展?

3.1.2 IOC解决上述问题

① 配置XML文件,将实现类交给Spring管理

在项目的src目录下增加配置文件名为 applicationContext.xml

在spring的解压路径下spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html 中最下方复制约束放入该配置文件,并在该文件中配置实现类。

<?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.itheima.spring.demo1.UserDAOImpl" >
 	</bean>
</beans>

② 编写测试方法

@Test
public void test02(){
	// 创建Spring的工厂
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	UserDao userDao = (UserDao) applicationContext.getBean("userDao");
	userDao.save();
}

3.2 DI

依赖注入,前提必须有IOC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来,即在Spring实例化该类时,其中的属性也自动赋值,修改上述 UserDaoImpl实现类增加 name 属性,并设置 set 方法。

/**
 * 用户管理DAO层实现类
 *
 */
public class UserDAOImpl implements UserDAO {
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public void save() {
		System.out.println("UserDAOImpl执行了..."+name);
	}

}

修改配置文件加入属性

<bean id="userDAO" class="com.itheima.spring.demo1.UserDAOImpl" >
    <property name="name" value="李东"/>
</bean>

重新运行上述测试类,运行结果为:

四.Spring工厂类

4.1 工厂类结构图

4.2 BeanFactory (老版本的工厂类)

特征:调用getBean的时候,才会生成类的实例

4.3 ApplicationContext (新版本的工厂类)

特征:加载配置文件的时候,就会将Spring管理的类都实例化。

ApplicationContext 有两个实现类

ClassPathXmlApplicationContext:加载类路径下的配置文件

FileSystemXmlApplicationContext:加载文件系统下的配置文件

/**
 * 加载磁盘上的配置文件
 */
public void demo3(){
	ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\applicationContext.xml");
	UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
	userDAO.save();
}

五.Spring的配置

5.1 Schema本地的配置

① 设置 Key 将下面这句话填入key中

② 设置 Location解压:spring-framework-4.2.4.RELEASE-schema.zip 在beans 目录下 选择 spring-beans-4.2.xsd

③ 设置 KeyType

5.2 Bean的相关配置

5.2.1  <bean>标签的id和name的配置

  • id           :使用了约束中的唯一约束。里面不能出现特殊字符的。
  • name     :没有使用约束中的唯一约束(理论上可以出现重复的,但是实际开发不能出现的),里面可以出现特殊字符,其余                     功能与id相同。应用在Spring和Struts1框架整合的时候 <bean name=”/user” class=””/>

5.2.2 Bean的生命周期的配置

  • init-method              :Bean被初始化的时候执行的方法
  • destroy-method       :Bean被销毁的时候执行的方法(Bean是单例创建,工厂关闭)

案例:

① 新建接口 CustomerDao 和 CustomerDaoImpl

public interface CustomerDao {
	public void save();
}
public class CustomerDaoImpl implements CustomerDao {
	
	public void setup(){
		System.out.println("CustomerDAOImpl被初始化了...");
	}

	@Override
	public void save() {
		System.out.println("CustomerDAOImpl的save方法执行了...");
	}
	
	public void destroy(){
		System.out.println("CustomerDAOImpl被销毁了...");
	}

}

② 在applicationContext.xml中增加如下配置

 		<!-- Spring的sBean的生命周期的配置=========== -->
<bean id="customerDao" class="dao.impl.CustomerDaoImpl" init-method="setup" destroy-method="destroy"/>

③ 编写测试方法

/**
 * 生命周期的配置
 */
public void test03(){
	ClassPathXmlApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
	CustomerDao customerDAO = (CustomerDao) applicationContext.getBean("customerDao");
	customerDAO.save();
	applicationContext.close();
}

运行结果:

5.2.3 Bean的作用范围的配置(重点)

  • scope                          :Bean的作用范围
    • singleton                  :默认的,Spring会采用单例模式创建这个对象。
    • prototype       :多例模式。(Struts2和Spring整合一定会用到)
    • request             :应用在web项目中,Spring创建这个类以后,将这个类存入到request范围中。
    • session             :应用在web项目中,Spring创建这个类以后,将这个类存入到session范围中。
    • globalsession  :应用在web项目中,必须在porlet环境下使用。但是如果没有这种环境,相对于session。

XML配置案例:

 		<!-- Spring的sBean的生命周期的配置=========== -->
<bean id="customerDao" class="dao.impl.CustomerDaoImpl" init-method="setup" destroy-method="destroy" scope="prototype" />

六.Spring中bean的管理(XML)

6.1 Spring中Bean的实例化方式

Bean已经都交给Spring管理,Spring创建这些类的时候,有几种方式:

6.1.1 无参构造方法的方式(默认)

/**
 * 无参数构造方法方式
 *
 */
public class Bean1 {

	public Bean1() {
		super();
		System.out.println("Bean1的无参数的构造方法执行了...");
	}

}
	<!-- 无参数构造方法 -->
<bean id="bean1" class="test.Bean1"></bean>
public void test05(){
	ClassPathXmlApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
	Bean1 b1 = (Bean1) applicationContext.getBean("bean1");
}

运行结果:

6.1.2 静态工厂实例化的方式

① 编写Bean2的静态工厂

/**
 * Bean2的静态工厂
 *
 */
public class Bean2Factory {

	public static Bean2 createBean2(){
		System.out.println("Bean2Factory中方法执行了...");
		return new Bean2();
	}
}

② 配置xml文件

	<!-- 静态工厂实例化 -->
<bean id="bean2" class="test.Bean2Factory" factory-method="createBean2"/>

③编写测试方法

/**
 * 静态工厂实例化
 */
public void demo2(){
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
	System.out.println(bean2);
}

6.1.3 实例工厂实例化的方式

① 编写Bean3的实例工厂

/**
 * Bean3的实例工厂
 *
 */
public class Bean3Factory {

	public Bean3 createBean3(){
		System.out.println("Bean3的实例工厂执行了...");
		return new Bean3();
	}
}

② 配置xml文件

	<!-- 实例工厂实例化 -->
<bean id="bean3Factory" class="test.Bean3Factory"></bean> 
<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"></bean> 

③编写测试方法

/**
 * 实例工厂实例化
 */
public void demo3(){
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
	System.out.println(bean3);
}

6.2 Spring的属性注入

6.2.1 构造方法的方式的属性注入

①编写汽车类

public class Car {
	private String name;
	private Double price;
	
	public Car(String name, Double price) {
		super();
		this.name = name;
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car [name=" + name + ", price=" + price + "]";
	}
	
}

②配置xml文件 

	<!-- 构造方法的方式 -->
	<bean id="car" class="demo4.Car">
		<constructor-arg name="name" value="宝马"/>
		<constructor-arg name="price" value="800000"/>
	</bean>

③测试方法

@Test
/**
 * 构造方法方式的属性注入
 */
public void demo1(){
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Car car = (Car) applicationContext.getBean("car");
	System.out.println(car);
}

6.2.2 set方法的方式的属性注入

①实体类

/**
 * set方法的属性注入
 *
 */
public class Car2 {
	private String name;
	private Double price;
	public void setName(String name) {
		this.name = name;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Car2 [name=" + name + ", price=" + price + "]";
	}
	
}

②配置xml文件

	<!-- set方法的方式 -->
  	<bean id="car2" class="demo4.Car2">
		<property name="name" value="奔驰"/>
		<property name="price" value="1000000"/>
	</bean> 

③测试方法

/**
 * set方法方式的属性注入
 */
public void demo2(){
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Car2 car2 = (Car2) applicationContext.getBean("car2");
	System.out.println(car2);
}

6.2.3 set方法设置对象类型的属性

①实体类

public class Employee {
	private String name;
	private Car2 car2;
	public void setName(String name) {
		this.name = name;
	}
	public void setCar2(Car2 car2) {
		this.car2 = car2;
	}
	@Override
	public String toString() {
		return "Employee [name=" + name + ", car2=" + car2 + "]";
	}
}

②配置xml文件

		<!-- set方法注入对象类型的属性 -->
	<bean id="employee" class="demo4.Employee">
		<!-- value:设置普通类型的值,ref:设置其他的类的id或name -->
		<property name="name" value="涛哥"/>
		<property name="car2" ref="car2"/>
	</bean> 
	<bean id="car2" class="demo4.Car2">
		<property name="name" value="奔驰"/>
		<property name="price" value="1000000"/>
	</bean>	

③测试方法

@Test
/**
 * set方法注入对象类型
 */
public void demo3(){
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Employee employee = (Employee) applicationContext.getBean("employee");
	System.out.println(employee);
}

6.2.4 P名称空间的属性注入(Spring2.5以后)

在约束中加入下面这句

配置类

		<!-- 改为p名称空间的方式 -->
	<bean id="car2" class="demo4.Car2" p:name="奇瑞QQ" p:price="30000"></bean>
	
	<bean id="employee" class="demo4.Employee" p:name="王东" p:car2-ref="car2"></bean>

6.2.5 SpEL的属性注入(Spring3.0以后)

SpEL:Spring Expression Language,Spring的表达式语言。

语法:#{SpEL}

编写实体类 CarInfo

public class CarInfo {
	private String name;
	
	public String getName() {
		return "摩托车";
	}
	
	public Double calculatorPrice(){
		return Math.random() * 3000;
	}
}

修改xml文件

		<!-- SpEL的属性注入 -->
	<bean id="carInfo" class="demo4.CarInfo">
	</bean>
	
	<bean id="car2" class="demo4.Car2">
		<property name="name" value="#{carInfo.name}"></property>
		<property name="price" value="#{carInfo.calculatorPrice()}"></property>
	</bean>
	
	<bean id="employee" class="demo4.Employee">
		<property name="name" value="#{'赵洪'}"></property>
		<property name="car2" value="#{car2}"></property>
	</bean>

6.2.6 集合类型属性注入

①实体类

/**
 * 集合属性的注入:
 *
 */
public class CollectionBean {
	private String[] arrs;
	private List<String> list;
	private Set<String> set;
	private Map<String,String> map;

	public void setArrs(String[] arrs) {
		this.arrs = arrs;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public void setSet(Set<String> set) {
		this.set = set;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	@Override
	public String toString() {
		return "CollectionBean [arrs=" + Arrays.toString(arrs) + ", list=" + list + ", set=" + set + ", map=" + map
				+ "]";
	}

	
}

②配置xml文件

	<!-- Spring的集合属性的注入============================ -->
	<!-- 注入数组类型 -->
	<bean id="collectionBean" class="demo4.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>

③测试类

@Test
public void demo1() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
	System.out.println(collectionBean);
}

 七.Spring分模块开发与项目优化

7.1 引入配置文件

在applicationContext.xml中引入其他配置文件

	<import resource="applicationContext2.xml"/>	

7.2 Spring项目优化

7.2.1 问题:

每次请求都会创建一个Spring的工厂,这样浪费服务器资源,应该一个项目只有一个Spring的工厂。

7.2.2 解决方案:

  • 在服务器启动的时候,创建一个Spring的工厂,创建完工厂,将这个工厂类保存到ServletContext中,每次使用的时候都从ServletContext中获取,使用ServletContextListener,监听ServletContext对象的创建和销毁。
  • 引入jar包:spring-web.jar
  • 配置监听器

  • 在Action中获取工厂

猜你喜欢

转载自blog.csdn.net/qq_30162219/article/details/86609170