第01章 Spring概述
1.框架
- 高度抽取可重用代码的一种设计
- 高度的通用性
- 多个可重用模块的集合,形成一个某个领域的整体解决方案
2.Spring框架
- Spring是一个开源框架
- Spring为简化企业级开发而生。使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能。同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁
- Spring是一个IOC(DI)和AOP容器框架
3.Spring优点
- 非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
- 依赖注入:DI(Dependency Injection),控制反转(IOC)最经典的实现
- 面向切面编程:AOP(Aspect Oriented Programming)
- 容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
- 组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用,在 Spring 中可以使用XML和Java注解组合这些对象
- 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)
4.IOC控制反转
IOC(Inversion Of Control):控制反转,控制资源的获取方式
主动式:(要什么资源都自己创建即可)
BookServlet{
BookService bs = new BookService();
//复杂对象的创建需要自己创建,代价昂贵
AirPlane ap = new AirPlane();
}
被动式:资源的获取不是自己创建,而是交给一个容器来创建和设置
BookServlet{
BookService bs;
public void checkout(){
bs.checkout();
}
}
容器:管理所有的组件(有功能的类),主动的new资源变为被动的接受资源,只要IOC容器管理的组件,
都能使用容器提供的强大功能
假设:BookServlet受容器管理,BookService也受容器管理;容器可以自动的探查出那些组件(类)
需要用到其他组件(类),容器帮我们创建BookService对象,并把BookService对象赋值过去
DI(Dependency Injection):依赖注入,容器能知道哪个组件(类)运行的时候,需要另外一个类
(组件)容器通过反射的形式,将容器中准备好的BookService对象注入(利用反射给属性赋值)
到BookServlet中
5.例子
- 使用Spring创建对象,为属性赋值
- 创建Person类
package com.jun.bean;
public class Person {
private String lastName;
private Integer age;
private String gender;
private String email;
public Person() {
super();
System.out.println("Person对象创建了...");
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Person [lastName=" + lastName + ", age=" + age + ", gender=" + gender + ", email=" + email + "]";
}
}
- 创建Spring配置文件
<?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">
<!-- 注册一个Person对象,Spring容器会自动创建这个Person对象 -->
<!--
一个bean标签可以注册一个组件(类的实例)
class属性:注册的组件的全类名
id属性:这个组件的唯一标识
-->
<bean id="person01" class="com.jun.bean.Person">
<!-- property标签为Person对象的属性赋值
name属性:指定Person对象的属性名
value属性:为这个Person对象的属性赋值
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<property name="email" value="zhangsan@qq.com"></property>
<property name="gender" value="男"></property>
</bean>
<bean id="person02" class="com.jun.bean.Person">
<property name="lastName" value="李四"></property>
</bean>
</beans>
- 测试通过Spring的IOC容器创建Person类实例
package com.jun.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jun.bean.Person;
public class IOCTest {
/**
* 从容器中拿到这个组件
* ApplicationContext:代表IOC容器
* ClassPathXmlApplicationContext:xml配置文件在ClassPath下
*
* 注意: 源码包(src,conf)开始的路径,称为类路径的开始
* 所有的源码包里面东西都会被合并放在类路径里面
* java:/bin/
* web:/WEB-INF/classes/
*/
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//根据spring的配置文件得到IOC容器对象
//org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml];
//nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/jun/bean/applicationContext.xml");
System.out.println("容器启动完成....");
Person bean = (Person)applicationContext.getBean("person01");
Object bean1 = applicationContext.getBean("person01");
System.out.println(bean == bean1);
//org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'person03' is defined
// System.out.println("==================");
// Object bean3 = applicationContext.getBean("person03");
}
}
6.总结
- Spring在创建IOC容器对象时,就已经完成了bean的创建和属性的赋值,默认是创建的bean是单例的
- 类路径,源码包(src,conf)开始的路径,称为类路径的开始,eclipse所有的源码包里面东西都会被合并放在类路径里面,java工程类路径:/bin/, web工程类路径:/WEB-INF/classes/
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("容器启动完成....");
Person bean = (Person)applicationContext.getBean("person01");
Object bean1 = applicationContext.getBean("person01");
System.out.println(bean == bean1);
}
- 类路径变化,ClassPathXmlApplicationContext获取相应spring配置文件也要变化,否则会抛出找不到 spring配置文件异常
@Test
public void test() {
/* org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from class path resource
[applicationContext.xml]; nested exception is java.io.FileNotFoundException:
class path resource [applicationContext.xml] cannot be opened because
it does not exist */
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/jun/bean/applicationContext.xml");
System.out.println("容器启动完成....");
Person bean = (Person)applicationContext.getBean("person01");
Object bean1 = applicationContext.getBean("person01");
System.out.println(bean == bean1);
}
- 容器中如果没有这个组件,获取组件会报异常
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("容器启动完成....");
Person bean = (Person)applicationContext.getBean("person01");
Object bean1 = applicationContext.getBean("person01");
System.out.println(bean == bean1);
/* org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'person03' is defined */
System.out.println("==================");
Object bean3 = applicationContext.getBean("person03");
}