一.spring框架的概述以及spring中基于xml的IOC配置
环境:
Idea:2019.3.1
系统:windows10 家庭版
Jdk: 8
spring:5.0.3 release
spring文档
项目代码
1.spring的概述
spring是什么
spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程) 为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
spring的发展历程和优势
发展历程:
1997年IBM提出了EJB的思想
1998年,SUN制定开发标准规范EJB1.0
1999年,EJB1.1发布
2001年,EJB2.0发布
2003年,EJB2.1发布
2006年,EJB3.0发布
Rod Johnson(spring之父)
Expert One-to-One J2EE Design and Development(2002)
阐述了J2EE使用EJB开发设计的优点及解决方案
Expert One-to-One J2EE Development without EJB(2004)
阐述了J2EE开发不使用EJB的解决方式(Spring雏形)
2017年9月份发布了spring的最新版本spring 5.0通用版(GA)
优势:
--方便解耦,简化开发
通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
--AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
--声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
--方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
--方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持
--降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMain、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低
--Java源码是经典学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无疑是Java技术的最佳实践的范例。
spring体系结构
2.程序的耦合以及解耦
程序的耦合
耦合:程序间的依赖关系, 类之间的依赖, 方法之间的依赖
解耦:降低程序间的依赖关系
实际开发中:
应该做到,编译器不依赖,运行时才依赖
解耦的思路:
第一步:使用反射创建对象,而避免使用new创建对象(如mysql驱动,这又会产生一个问题,这个字符串是写死的,如果后来要修改数据库驱动,就很麻烦)
第二部:通过读取配置文件来获取要创建的对象的全限定名,唯一标识符=全限定类名(key==value)格式,配置文件可以是xml,也可以是properties
3.IOC概念和spring中的IOC
概念
常规创建对象方式:自主创建对象,通过new关键字,获取资源创建对象
被动接受获取对象:通过一个工厂对资源进行分配,程序只能被动接受对象,这就叫控制反转(IoC)
Ioc的作用
削减计算机程序的耦合(解除我们代码中的依赖关系)
spring中的IoC
sipring的开发包Spring仓库
spring对bean的管理细节(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">
<!-- 把对象的创建交给spring来管理-->
<!--
spring对bean的管理细节:
1.创建bean对象的三种方式
第一种方式:使用默认构造函数创建
在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
意思就是,如果你在这个bean类里面写了个带参构造方法,而没有空参构造方法,那么就会报错
例子:
<bean id="accountService" class="com.cbw.service.impl.AccountServiceImpl" scope="singleton"></bean>
第二种方式:使用普通工厂中的方法创建对象
使用某个类中的方法创建对象,并存入spring容器,意思就是,可能有个Factory类,他有个方法是
return一个AccountServiceImpl,即你需要的实现类
(1)先获取一个工厂的Bean对象
(2)通过factory-bean(用我们刚刚获取的工厂对象),factory-method(指明哪个方法)两个属性获取我们所需的Bean对象
例子:
<bean id="instanceFactory" class="com.cbw.Factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
第三种方式:使用工厂中的静态方法创建对象
使用某个类中的静态方法创建对象,并存入spring容器
class属性写那个静态工厂的全限定类名,factory-method写那个静态方法
例子:
<bean id="accountService" class="com.cbw.Factory.StaticFactory" factory-method="getAccountService"></bean>
2.bean对象的作用范围
bean标签的scope属性:
作用:用于指定bean的作用范围
取值:常用的就是单例的,多例的
singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session(4.0版本的特性,5.0版本已不支持)
3.bean对象的生命周期
单例对象
出生:当容器创建,对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同
多例对象
出生:当我们使用对象时spring为我们创建
活着:对象只要是在使用中,就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,由java垃圾回收器回收
例子:
<bean id="accountService" class="com.cbw.service.impl.AccountServiceImpl" scope="prototype" init-method="init" destroy-method="destroy"></bean>
-->
</beans>
小插曲:global-session
获取IoC核心容器(client)
package com.cbw.ui;
import com.cbw.dao.IAccountDao;
import com.cbw.service.IAccountService;
import com.sun.org.apache.xml.internal.utils.XML11Char;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
auther:iwishing
获取spring的IoC容器,并根据id获取对象
ApplicationContext的三个常用实现类
ClassPathXmlApplicationContext:它可以加载类路径下的xml文件,要求配置文件必须在类路径下,否则加载不了(实际开发更常用)
FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件,前提是有访问权限
AnnotationConfigApplicationContext:它是用于读取注解创建容器
ApplicationContext和BeanFactory的区别
ApplicationContext:--------------单例对象适用(一创建就存进去),开发时常用
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件
中配置的对象
测试方法:给对象添加一个构造函数,里面打印一句语句,然后yogaApplicationContext构造容器的时候可以看到这条语句打印出来了
BeanFactory:--------------多例对象适用(即用即创),顶层接口,功能没有子接口完善,故开发常使用上个接口
它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象
public class Client {
public static void main(String[] args) {
//ApplicationContext接口
//1.通过ClassPathXmlApplicationContext实现类获取核心容器对象
//ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过FileSystemXmlApplicationContext实现类获取核心容器对象
ApplicationContext ac = new FileSystemXmlApplicationContext("E:\\myCodeSpace\\mySpringDemo\\mySpringDemo_spring\\src\\main\\resources\\applicationContext.xml");
//2.根据id获取bean对象
//根据唯一标识符,获取object对象再强转
IAccountService as = (IAccountService)ac.getBean("accountService");
//根据字节码自己强转
IAccountDao ad = ac.getBean("accountDao",IAccountDao.class);
as.saveAccount();
//BeanFactory接口
//1.通过ClassPathResource实现类找到配置文件
Resource resource = new ClassPathResource("applicationContext.xml");
//2.通过XmlBeanFactory实现类构建容器
BeanFactory beanFactory = new XmlBeanFactory(resource);
//3.通过id创建bean对象
IAccountService as = (IAccountService) beanFactory.getBean("accountService");
as.saveAccount();
}
}