- Spring的概述
- Spring的入门
什么是spring框架?
- Spring是一个开源框架
- Spring为简化企业级应用开发而生。使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能
- Spring使javaSE/JavaEE的一站式框架
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
◆目的:解决企业应用开发的复杂性
◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
◆范围:任何Java应用
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
Spring的优点
- 方便解耦,简化开发
- spring就是个大工厂,将所有对象创建和依赖关系维护,交给Spring管理
- AOP编程的支持
- Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
- 只需要通过配置就可以完成对事务的管理,而且无需手动编程
- 方便程序测试
- Spring对junit4支持,可以用过注解方便的测试Spring程序
- 方便集成各种优秀框架
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibertnate、MyBatis等)的直接支持
- 降低JavaEE API的使用难度
- Spring对JavaEE开发中非常难用的一些API(JDBC、Javamail、远程调用等),都提供了封装,使这些API应用难度大大降低
Spring IOC的底层原理实现
传统方式的开发
UserService us=new UserService();
↓ 面向接口编程
UserService us=new UserSerivceImpl();
↓ ocp原则:open-close 原则,对程序拓展是open的,对修改程序代码是close
↓ 尽量做到不修改程序的源码,实现对程序的扩展
工厂模式
工厂类创建 示例对象
1 |
class { |
工厂+反射+配置文件
1 |
<bean id="us" class="com.imooc.UserServiceImpl"/> |
1 |
class { |
Spring IOC的快速入门案例
- 下载Spring开发包
https://repo.spring.io/libs-release-local/org/springframework/spring/
- 复制Spring开发jar包到工程
- 理解IOC控制反转和DI依赖注入
- 编写Spring核心配置文件
- 在程序中读取Spring配置文件,通过Spring框架获得Bean,完成相应操作
- 创建Maven工程
pom.xml
spring相关依赖
spring-core/spring-context/spring-beans/spring-logging
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sipc</groupId>
<artifactId>food</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>food Maven Webapp</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<finalName>food</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
- 创建applicationContext.xml
- 创建接口
- 继承接口
- SpringDemo1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package ioc.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo1 {
public void demo1(){
UserService userService=new UserServiceImpl();
userService.sayHello();
}
// spring的方式实现
public void demo2(){
//创建Spring的工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获得类
UserService userService=(UserService) applicationContext.getBean("userService");
userService.sayHello();
}
}
IOC和DI的概念
- IOC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建UserService对象的控制权,交由
Spring框架处理
- 简单说,就是创建UserService对象控制权被反转到了Spring框架
- DI Dependency Injection 依赖注入的概念,就是在Spring创建这个对象的过程中,
将这个对象所依赖的属性注入进去
1 |
|
Spring Bean管理
三种实例化Bean的方式
- 使用类构造器实例化(默认无参数)
- 创建java/demo2/Bean1
1
2
3
4
5
6
7
8package demo2;
//实例化的三种方式:采用无参数的构造方法的参数
public class Bean1 {
public Bean1(){
}
}- 配置spring config applicationContext.xml
1
<bean id="bean1" class="demo2.Bean1"/>
1
3. SpringDemo2中(测试)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package demo2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo2 {
public void demo1(){
//创建工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获得类的实例
Bean1 bean1= (Bean1) applicationContext.getBean("bean1");
}
}
- 使用静态工厂方法实例化(简单工厂模式)
- 创建java/demo2/Bean2
1
2
3
4
5package demo2;
//静态工厂实例化方式
public class Bean2 {
}- 创建demo2/Bean2Factory
1
2
3
4
5
6
7
8
9package demo2;
public class Bean2Factory {
//第二种:Bean2的静态工厂
public static Bean2 createBean2(){
System.out.println("Bean2Factory的方法已经执行了");
return new Bean2();
}
}
- applicationContext.xml
1
<bean id="bean2" class="demo2.Bean2Factory" factory-method="createBean2"/>
- SpringDemo2中(包含bean3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package demo2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo2 {
public void demo1(){
//创建工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获得类的实例
Bean1 bean1= (Bean1) applicationContext.getBean("bean1");
}
public void demo2(){
//创建工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获得类的实例
Bean2 bean2= (Bean2) applicationContext.getBean("bean2");
}
public void demo3(){
//创建工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获得类的实例
Bean3 bean3= (Bean3) applicationContext.getBean("bean3");
}
}
- 使用实例工厂方法实例化(工厂方法模式)
- java/demo2/Bean3
1 |
package demo2; |
- demo2/Bean3Factory
1 |
package demo2; |
- applicationContext.xml
1 |
<bean id="bean3Factory" class="demo2.Bean3Factory"/> |
- SpringDemo2
1 |
package demo2; |
Bean的配置
- id和name
- 一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称
- id 属性在IOC容器中必须是唯一的
- 如果Bean的名称中含有特殊字符,就需要使用name属性
- class
- class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例
Bean的作用域
| 类别 | 说明 |
|---|---|
| singleton | 在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在 |
| prototype | 每次调用getBean()时都会返回一个新的实例 |
| request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
| session | 同一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean,该作用域仅适用于WebApplicationContext环境 |
applicationContext.xml
1 |
|
demo3/Person
1 |
package com.majiajun.demo3; |
demo3/SpringDemo3
1 |
package com.majiajun.demo3; |
Bean的生命周期
1 |
<bean id="man" class="demo3.Man" init-method="setup" destroy-method="teardown"></bean> |
Bean的生命周期的完整过程
- instantiate bean对象实例化
1
2
3
4
5public class Man(){
public Man(){
System.out.println("第一步:对象的实例化");
}
} - poprlate properties封装属性
1
2
3
4
5
6
7public class Man{
private String name;
public void setName(String name) {
System.out.println("第二步:设置属性");
this.name = name;
} - 如果Bean实现BeanNameAware执行setBeanName
- 如果Bean实现BeanFactoryAware或者ApplicationContextAware设置工厂 setBeanFactory或者上下文对象setApplicationContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public class Man implements BeanNameAware, ApplicationContextAware {
private String name;
public void setName(String name) {
System.out.println("设置属性");
this.name = name;
}
public Man(){
System.out.println("Man被实例化");
}
public void setup(){
System.out.println("Man被初始化");
}
public void teardown(){
System.out.println("Man被销毁了");
}
public void setBeanName(String s) {
System.out.println("第三步:设置Bean的");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:了解工厂的信息");
}
} - 如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.majiajun.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:初始化前方法");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第八步:初始化后方法");
return bean;
}
} - 如果Bean实现InitializingBean执行afterPropertiesSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41package com.majiajun.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean {
private String name;
public void setName(String name) {
System.out.println("设置属性");
this.name = name;
}
public Man(){
System.out.println("Man被实例化");
}
public void setup(){
System.out.println("Man被初始化");
}
public void teardown(){
System.out.println("Man被销毁了");
}
public void setBeanName(String s) {
System.out.println("第三步:设置Bean的");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:了解工厂的信息");
}
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后");
}
} - 调用
指定初始化方法init - 如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessAfterInitialization
- 执行业务处理(自己定义的方法),如下
1
2
3
4
5public class Man{
public void run(){
System.out.println("第九步:执行业务方法");
}
} - 如果Bean实现DisposableBean执行destory
1
2
3
4
5public class Man implements DisposableBean{
public void destory()throws Exception{
System.out.println("第十步:执行Spring的销毁方法");
}
} - 调用
指定销毁方法customerDestory
Spring容器中Bean的生命周期
- 演示如何增强一个类中的方法
Spring的属性注入
- 对于类成员变量,注入方式有三种
- 构造函数注入
- 通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用
- 属性settrt方法注入
- 接口注入
- 构造函数注入
- Spring支持前两种




近期评论