源码链接,自行下载
1.Spring介绍
1.1 Spring概述
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架。 它是为了解决企业应用开发的复杂性而创建的。
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
1.2 Spring好处
方便解耦,简化开发:
- Spring就是一个大工厂,专门负责生成Bean,可以将所有对象创建和依赖关系维护由Spring管理
AOP编程的支持:
- Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无需手动编程
方便程序的测试:
- Spring对Junit4支持,可以通过注解方便的测试Spring程序
方便集成各种优秀框架:
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的支持
降低JavaEE API的使用难度 Spring:
- 对JavaEE开发中一些难用的API(JDBC、JavaMail、远程调webservice用等),都提供了封装,使这些API应用难度大大降低
1.3 Spring体系结构
Spring 框架是一个分层架构,,它包含一系列的功能要素并被分为大约20个模块。
1.4 在项目中的架构
web层:Struts,SpringMVC
dao层:Hibernate,mybatis
2.spring快速入门
2.1.导入依赖 到 pom.xml
<properties>
<!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 5.0.2.RELEASE 找不到 org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping-->
<spring.version>4.1.4.RELEASE</spring.version>
</properties>
<dependencies>
<!-- javaEE相关的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0-b01</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.23</version>
</dependency>
<!-- spring4 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- 事务管理的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring集成jdbc的jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springMvc的jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- springmvc自动转jSON的jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- mybatis集成spring的jar -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- spring集成mybatis的jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
2.2.服务层创建 UserService接口 和相应的UserServiceImpl实现类 ,控制层创建UserController
UserService接口
public interface UserService {
void show();
}
UserServiceImpl
public class UserServiceImpl implements UserService {
public void show() {
System.out.println("实现方法");
}
}
UserController 要有 属性的get set tostring方法 和类的构造器 【Alt+Ins 可快速创建】
public class UserController {
private UserService userService;
private int pageNum;
public void show(){
userService.show();
}
........
2.3.测试层 创建TestSpring
2.3.1 方法一 原始方式 获取UserServiceImpl实现类对象
//用控制层的show方法调用服务层实现类的show方法
//用控制层的show方法调用服务层实现类的show方法
@Test
public void test1(){
UserController userController=new UserController();
userController.setUserService(new UserServiceImpl());
userController.show();
}
测试结果
实现方法
进程已结束,退出代码 0
2.3.2 方法二 bean方式1 获取UserServiceImpl实现类对象
先在resources创建 applicationContext.xml
导入约束 applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd ">
在 applicationContext.xml 写bean id 识别相应的bean对象 ,然后自动去new class里面的那个类的对象
<!-- 相当于new UserServiceImpl实现类对象--> <bean id="userServiceByID" name="userServiceByName" class="com.pratice.service.Impl.UserServiceImpl"></bean>
测试
//bean方式1
@Test
public void test2(){
// 加载Spring容器 单例模式
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过id 获得实现类对象
UserService userService=(UserService)context.getBean("userServiceByID");
UserController userController=new UserController();
userController.setUserService(userService);
userController.show();
}
测试结果
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
实现方法
警告不用理
2.3.3 方法二 工厂模式装配bean
创一个User类
public class User {
private int id;
private String name;
private User user;
private Book[] bookArray;
private List list;
private Set set;
private Map map;
private Properties properties;
...... 接下来要用
建立一个工厂类管理 User对象
public class CreateUserFactory {
// 动态装配
public User getUser1(){
return new User();
}
// 静态装配
public static User getUser2(){
return new User();
}
}
在 applicationContext.xml 写
<!--工厂模式装配bean--> <!-- 静态装配 class写要工厂类的全类名 factory-method 写获取对象静态方法名--> <bean id="user" class="com.pratice.bean.factory.CreateUserFactory" factory-method="getUser2"></bean>
<!-- 动态装配 单建立一个工厂类的bean对象,用另一个bean 管理这个工厂 --> <bean id="factory" class="com.pratice.bean.factory.CreateUserFactory"></bean> <bean id="user2" factory-bean="factory" factory-method="getUser1"></bean>
测试
//工厂模式装配bean
@Test
public void test3(){
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
// 静态方法
User user=(User)context.getBean("user");
System.out.println(user.toString());
// 动态实例
User user2=(User)context.getBean("user2");
System.out.println(user2.toString());
}
测试结果
User{id=0, name='null', user=null, bookArray=null, list=null, set=null, map=null, properties=null}
User{id=0, name='null', user=null, bookArray=null, list=null, set=null, map=null, properties=null}
进程已结束,退出代码 0
2.4 【IoC】
IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建UserService对象的控制权,交由Spring框架管理,简单说,就是创建UserService对象控制权被反转到了Spring框架。
2.5 DI 依赖注入
- Dependency Injection 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件。
在 applicationContext.xml 写
set 注入和 构造器注入
<!-- 给UserController进行注入 (就是赋值的意思)--> <bean id="userController" class="com.pratice.controller.UserController"> <!-- set注入 调用属性的set方法赋值--> <!-- <property name="userService" ref="userServiceByID"></property>--> <!-- <property name="pageNum" value="10"></property>--> <!-- 构造器注入 调用相应的构造器赋值--> <constructor-arg name="userService" ref="userServiceByID"></constructor-arg> <constructor-arg name="pageNum" value="10"></constructor-arg> </bean>
测试
//构造器和set注入测试
@Test
public void test5(){
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
UserController userController=(UserController)context.getBean("userController");
System.out.println(userController.toString());
}
测试结果
UserController{userService=com.pratice.service.Impl.UserServiceImpl@4e928fbf, pageNum=10}
进程已结束,退出代码 0
在 applicationContext.xml 写
p命名空间注入 p:属性=值
<!--p命名空间注入--> <bean id="user3" class="com.pratice.bean.User" scope="prototype" p:id="#{1+1}" p:name="#{'hello'.length()}"></bean> <bean id="user4" class="com.pratice.bean.User" scope="prototype" p:id="#{1}" p:name="#{user3.name}" p:user-ref="user3"></bean>
测试
// p命名空间注入
@Test
public void test6(){
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
User user3=(User)context.getBean("user3");
System.out.println(user3.toString());
User user4=(User)context.getBean("user4");
System.out.println(user4.toString());
}
测试结果
User{id=2, name='5', user=null, bookArray=null, list=null, set=null, map=null, properties=null}
User{id=1, name='5', user=User{id=2, name='5', user=null, bookArray=null, list=null, set=null, map=null, properties=null}, bookArray=null, list=null, set=null, map=null, properties=null}
进程已结束,退出代码 0
补充 SpEL表达式【了解】
#{123}、#{'jack'} : 数字、字符串
#{beanId} :另一个bean引用
#{beanId.propName} :操作数据
#{beanId.toString()} :执行方法
#{T(类).字段|方法} :静态方法或字段
集合注入【array list set map properties】
<!-- 集合注入--> <bean id="book1" class="com.pratice.bean.Book" p:id="1" p:name="西游记"></bean> <bean id="book2" class="com.pratice.bean.Book" p:id="2" p:name="红楼梦"></bean> <bean id="book3" class="com.pratice.bean.Book" p:id="3" p:name="三国演义"></bean> <bean id="user5" class="com.pratice.bean.User"> <property name="bookArray"> <array> <ref bean="book1"></ref> <ref bean="book2"></ref> <ref bean="book3"></ref> </array> </property> <property name="list"> <list> <ref bean="book1"></ref> <ref bean="book2"></ref> <ref bean="book3"></ref> <value>第四</value> </list> </property> <property name="set"> <set> <ref bean="book1"></ref> <ref bean="book2"></ref> <ref bean="book3"></ref> </set> </property> <property name="map"> <map> <entry key="1" value-ref="book1"></entry> <entry key-ref="book2" value="2"></entry> </map> </property> <property name="properties"> <props> <prop key="a">1+1</prop> <prop key="b">"2+2"</prop> <prop key="c">#{3+3}</prop> <prop key="d">"The value is #{4+4}"</prop> <prop key="e">[5+5]</prop> <prop key="f">#{6+6}</prop> </props> </property> </bean>
测试
//集合注入
@Test
public void tes4(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user5=(User)context.getBean("user5");
System.out.println(user5.toString());
}
测试结果
User{id=0, name='null', user=null, bookArray=[Book{id=1, name='西游记'}, Book{id=2, name='红楼梦'}, Book{id=3, name='三国演义'}], list=[Book{id=1, name='西游记'}, Book{id=2, name='红楼梦'}, Book{id=3, name='三国演义'}, 第四], set=[Book{id=1, name='西游记'}, Book{id=2, name='红楼梦'}, Book{id=3, name='三国演义'}], map={1=Book{id=1, name='西游记'}, Book{id=2, name='红楼梦'}=2}, properties={a=1+1, b="2+2", c=6, d="The value is 8", e=[5+5], f=12}}
进程已结束,退出代码 0
3.bean的生命周期【了解】
生命周期图
生命周期图解释
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
执行业务处理
9.如果Bean实现 DisposableBean 执行 destroy
10.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy