Spring是什么
Spring是一个分层的“一站式”轻量级开源框架。很多人称它:Spring“全家桶“。
Spring的优势
- 方便解耦,简化开发
通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。 - AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。 - 声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。 - 方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。 - 方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。 - 降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
SpringIOC
- 什么是IOC
IOC,它是Inverse of Control的缩写,中文含义是控制反转,表示将对象的创建权力反转给Spring框架。 - IOC的作用:降低程序耦合度
- Spring IOC快速入门
① 创建maven项目,引入依赖
<dependencies>
<!-- springIOC的依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- 日志环境的依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
<!-- 单元测试的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
② 引入log4j的配置文件log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
③ 创建一个接口和实现类
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao{
public void save() {
System.out.println("持久层:保存");
}
}
④ 创建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">
<!-- id属性指定bean的唯一标识;class属性指定bean的全路径名。 -->
<bean id="userDao" class="com.ityang.dao.impl.UserDaoImpl"></bean>
</beans>
⑤ 测试
public class TestIOC {
@Test
public void test1(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.save();
}
}
Spring中的工厂
Spring中提供了两个工厂接口:
- ApplicationContext
- BeanFactory
- ApplicationContext
使用该接口可以获得Bean对象,有两个具体的实现类
① ClassPathXmlApplicationContext – 加载类路径下的Spring配置文件
@Test
public void test(){
//创建Spring工厂(创建IOC容器)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
② FileSystemXmlApplicationContext – 加载本地磁盘下的Spring配置文件
@Test
public void test(){
//创建Spring工厂(创建IOC容器)
ApplicationContext ac = new FileSystemXmlApplicationContext("C:/spring/applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
- BeanFactory
BeanFactory是Spring框架早期的创建Bean对象的工厂接口,也可以获得Bean对象
@Test
public void test(){
// 早期版本使用,现已过时
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserDao userDao = (UserDao) factory.getBean("userDao");
userDao.save();
}
- BeanFactory和ApplicationContext的区别
BeanFactory采取延迟加载,第一次getBean时才会初始化Bean;而ApplicationContext在加载applicationContext.xml时候就会创建具体的Bean对象的实例。
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">
<bean id="userDao" class="com.ityang.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
</beans>
- id属性:bean的唯一标识
- class属性:bean的全路径名
- scope属性:
① singleton:表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
② prototype:表示每次获得bean都会生成一个新的对象
③ request:表示在一次http请求内有效(只适用于web应用)
④ session:表示在一个用户会话内有效(只适用于web应用)
⑤ globalSession:表示在全局会话内有效(只适用于web应用) - init-method属性:当bean被载入到容器的时候会调用init-method属性指定的方法
- destroy-method属性:当bean从容器中删除的时候会调用destroy-method属性指定的方法
// 测试时手动调用关闭方法,才能看到销毁的效果,显示关闭ioc+bean一定要是单例的
((ClassPathXmlApplicationContext)ac).close();
Spring生成Bean的三种方式
- 方式一:
默认调用无参构造方法实例化bean - 方式二:
静态工厂实例化方式,通过调用工厂类的静态方法来生成bean
// 接口
public interface DeptDao {
public void save();
}
// 实现类
public class DeptDaoImpl implements DeptDao{
@Override
public void save() {
System.out.println("持久层:部门保存...");
}
}
public class Factory {
// 静态工厂方法
public static DeptDao create(){
System.out.println("调用了静态工厂方法");
return new DeptDaoImpl();
}
}
<?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">
<bean id="deptDao" class="com.ityang.factory.Factory" factory-method="create"></bean>
</beans>
注意:class属性写的不是DeptDaoImpl的全路径名,而是工厂类的全路径名;factory-method:指定工厂类中静态方法的名字
- 方式三:
实例工厂实例化方式
public class Factory {
public DeptDao create(){
System.out.println("调用了实例工厂方法");
return new DeptDaoImpl();
}
}
<!-- 实例工厂方法来实例化 -->
<bean id="factory" class="com.ityang.factory.Factory"></bean>
// factory-bean:指定工厂bean的id;factory-method:指定工厂bean的实例方法的名字
<bean id="deptDao" factory-bean="factory" factory-method="create"></bean>