建设企业网站的目的以及意义,wordpress二维码活码,东莞市哪里有做网站公司,做招聘网站没有数据1. Spring 基础
1.1 什么是Spring框架#xff1f;它能带来那些好处#xff1f;
Spring 是一个开源的轻量级的 Java 开发框架#xff0c;可以帮助开发人员更高效的进行开发#xff0c;主要优势在于简化开发和框架整合。
Spring框架整合了很多模块#xff0c;这些模块可以…1. Spring 基础
1.1 什么是Spring框架它能带来那些好处
Spring 是一个开源的轻量级的 Java 开发框架可以帮助开发人员更高效的进行开发主要优势在于简化开发和框架整合。
Spring框架整合了很多模块这些模块可以协助我们开发。例如Spring中的两大核心技术IoC (Inversion of Control:控制反转) 和 AOP (Aspect-Oriented Programming : 面向切面编程)可以很方便的支持对数据库的访问并集成第三方组件例如调度缓存等等还支持单元测试。
1.2 Spring的组成是什么包含哪些模块
Spring 4.x版本 Spring 5.x 版本
Spring5.x 版本中 Web 模块的 Portlet 组件已经被废弃掉同时增加了用于异步响应式处理的 WebFlux 组件。 Core ContainerAOPData Access/IntegrationWebTest…
每个模块的作用和技术
1.3 Spring, Spring MVC, Spring Boot 之间的关系
首先回答什么是 SpringSpring MVCSpring Boot 联系
Spring MVC 是 Spring 众多模块中的一个重要模块可以让 Spring 快速构建出一个 MVC 架构的 Web 程序。
MVC 是指模型Model视图View控制器Controller的简写MVC架构的核心思想是将业务逻辑数据显示分离来组织代码以简化 Web 程序的开发。
与三层开发模型 ControllerServiceDao 的关系是 Spring 进行开发的过程中需要用 XML 或者 Java 进行显示的配置比较繁琐。而 Spring Boot 简化了这些配置减少了配置文件做到了开箱即用。
如何做到简化配置文件的原理是什么
2 Spring 核心技术
什么是IoC/DI 思想
IoC控制反转对象的创建权交给外部的 IoC 容器DI 依赖注入绑定对象与对象之间的依赖关系
什么是 IoC 容器
Spring 创建的用来存放所创建对象的容器
什么是 Bean?
IoC 容器中存放的一个个对象就是 Bean 或者 Bean 对象
2.1 Spring IoC DI
应该要补充原理的这里
2.2 案例
IoC 的入门案例 首先创建一个 Maven 工程 在 pom 中添加 spring-context 依赖 创建BookService,BookServiceImplBookDao和BookDaoImpl四个类 **添加 spring 配置文件**在 resource 目录下添加 applicationContext.xml 文件 用于配置 bean 信息 **在配置文件中对 Bean 进行配置**设置 bean 的名字和类型 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- id 为 bean 的名字 class 为 bean 对象所属的类--bean idbookDao classcom.rainsun.Dao.Impl.BookDaoImpl/bean idbookService classcom.rainsun.Service.Impl.BookServiceImpl/
/beans获取 IoC 容器把我们配置好的 Bean 文件进行解析获得一个存放着Bean的容器 public class App2 {public static void main(String[] args) {// IoC 容器获取传入Bean的配置文件ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);}
}从容器中获取 Bean 对象 并进行方法调用 public class App2 {public static void main(String[] args) {// IoC 容器获取ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);// 获取 Bean
// BookDao bookDao (BookDao)ctx.getBean(bookDao);
// bookDao.save();BookService bookService (BookService)ctx.getBean(bookService);bookService.save();}
}问题这里完成了控制反转将对象的创建权交给了Spring也可以获取对象但是 Service 层中依然存在 Dao 层的 new 对象这需要依赖注入(DI来解决
DI 入门案例 去掉原先 new 创建对象的方式改为使用 set 方法进行Bean对象赋值 public class BookServiceImpl implements BookService {// 去掉 new 的实现方式改为 DI依赖注入
// private BookDao bookDao new BookDaoImpl();private BookDao bookDao;Overridepublic void save() {System.out.println(Book service save);bookDao.save();}// 通过调用set方法进行依赖注入public void setBookDao(BookDao bookDao) {this.bookDao bookDao;}
}修改 Spring 配置文件为 bookService 对象添加一个依赖 把 Ioc 容器中的 bookDao 对象绑定到 bookService 对象的 bookDao 属性上这个绑定的实现要靠 setter 方法 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- id 为 bean 的名字 class 为 bean 对象所属的类--bean idbookDao classcom.rainsun.Dao.Impl.BookDaoImpl/bean idbookService classcom.rainsun.Service.Impl.BookServiceImpl
!-- name 指 BookServiceImpl 中的 bookDao 成员变量ref 指 IoC 容器存放的 bookDao Bean对象 --property namebookDao refbookDao//bean
/beans3 IoC相关 Bean 的创建
3.1 Bean 配置相关
基础配置 id, class, name
bean id namexxx xx xxx class/beanid 表示 Bean 的名字class 是bean的类型也就是属于哪个实现类的name 是 bean 的别名可以有多个用逗号分号空格 进行分隔。通过别名也可以获取 Bean 对象
作用范围 scope
bean id namexxx xx xxx class scopesingleton/prototype/bean可选范围
singleton默认为单例模式获取的同一名字的 bean 对象为同一个对象地址相同prototype非单例
思考
Bean 为什么默认为单例的 单例模式下 IoC 容器中只有该类的一个对象便于对象的复用避免了对象的频繁创建和销毁 哪些 Bean 对象适合交给容器管理 表现层对象业务层对象数据层对象工具对象它们的对象只创建一次就够了后面可以反复使用 哪些 Bean 对象不适合交给容器进行管理 封装实例的域对象什么意思呢记录了一些属性值状态在不断的变化的对象。会引发线程安全问题所以不适合
3.2 Bean 实例化
我们将对象交给 Spring 的 IoC 容器进行创建了但是容器是如何创建的呢
构造方法实例化
我们为 BookDaoImpl 添加一个 public 的构造方法
public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println(book dao constructor is running);}Overridepublic void save() {System.out.println(Book dao save);}
}然后获取 bookDao 对象调用save 方法可以发现构造方法被调用了
book dao constructor is running
Book service save
Book dao save如果将构造方法改为私有的 private构造方法依然被调用
private BookDaoImpl() {System.out.println(book dao constructor is running);
}说明无论构造函数是公开还是私有的spring底层都能通过构造函数创建出一个bean对象。也就是说Spring底层是利用反射实现的。
如果我们在无参构造函数中添加一个参数Spring就会报错没有默认构造函数
进一步说明Spring底层是使用类的无参构造方法
静态工厂实例化
首先环境准备创建一个工程提供实现类的一个实例
实现的接口
package com.rainsun.Dao;
public interface OrderDao {public void save();
}实现类
package com.rainsun.Dao.Impl;
import com.rainsun.Dao.OrderDao;
public class OrderDaoImpl implements OrderDao {Overridepublic void save() {System.out.println(order dao save ...);}
}工厂类提供静态方法返回一个实例
package com.rainsun.factory;
import com.rainsun.Dao.Impl.OrderDaoImpl;
import com.rainsun.Dao.OrderDao;
public class OrderDaoFactory {public static OrderDao getOrderDao(){return new OrderDaoImpl();}
}从工厂中获取对象
package com.rainsun;
import com.rainsun.Dao.OrderDao;
import com.rainsun.factory.OrderDaoFactory;
public class AppForInstanceOrder {public static void main(String[] args) {OrderDao orderDao OrderDaoFactory.getOrderDao();orderDao.save();}
}如何将getOrderDao中创建的对象交给Spring管理呢
这需要用到 Spring 中静态工厂实例化的知识
在配置文件中添加 工厂方法的全类名(class) 和 工厂方法factory-method) getOrderDao
bean idorderDao classcom.rainsun.factory.OrderDaoFactory factory-methodgetOrderDao /就可以把 getOrderDao 创建的 orderDao对象加入到容器我们也可以通过 orderDao的名字获取到对应的bean然后调用对应的方法了
实例工厂实例化
相比与静态工厂实例工厂需要创建工厂的实例才能创建对象。也就是方法没有了 static 修饰
package com.rainsun.factory;
import com.rainsun.Dao.Impl.OrderDaoImpl;
import com.rainsun.Dao.OrderDao;
public class OrderDaoFactory {public OrderDao getOrderDao(){return new OrderDaoImpl();}
}获取对象需要创建工厂实例再调用方法
public class AppForInstanceOrder {public static void main(String[] args) {//创建实例工厂对象OrderDaoFactory orderDaoFactory new OrderDaoFactory();//创建实例工厂对象OrderDao orderDao orderDaoFactory.getOrderDao();orderDao.save();}
}如何将实例工厂创建的对象交给 Spring 管理呢
我们也需要创建一个工厂的实例对象然后用 factoryBean 指向该对象再指明调用的工厂方法
bean idorderDaoFactory classcom.rainsun.factory.OrderDaoFactory/bean idorderDao factory-methodgetOrderDao factory-beanorderDaoFactory/首先实例化工厂对象 调用对象中的方法创建bean factory-bean工厂的实例对象 factory-method工厂中具体创建对象的方法名称
FactoryBean的使用
实际上创建的工厂 bean 只是为了配合后面创建对象bean的使用且每次创建对象bean的时候都需要指定 工厂bean对象。比较麻烦Spring 提供了一个 FactoryBean接口的方式简化开发
实例工厂实现 FactoryBean 接口重写接口中的方法
public class OrderDaoFactoryBean implements FactoryBeanOrderDao {Override // 代替原始工厂中创建对象的方法public OrderDao getObject() throws Exception {return new OrderDaoImpl();}Overridepublic Class? getObjectType() {return OrderDao.class;}
}Spring的bean配置中就可以只写一行配置指明id和class就行
bean idorderDao classcom.rainsun.factory.OrderDaoFactoryBean/继承的 FactoryBean接口中有三个方法
T getObject() throws Exception;Class? getObjectType();default boolean isSingleton() {return true;
}getObject 重写返回创建的对象getObjectType重写返回被创建对象的Class对象isSingleton有默认值为单例模式。如果重写返回 false 就是非单例的
3.3 Bean 的生命周期
Bean的生命周期是指 bean 对象从创建到销毁的整个过程。
我们主要关注 Bean 的生命周期控制控制 bean 创建后和销毁前做一些操作。
如何将这些控制操作添加进去呢
通过在配置文件中指定初始化方法和销毁方法的方式实现
生命周期设置
生命周期的控制分为两个阶段
bean 创建之后添加一些操作内容例如初始化用到的资源bean 销毁之前添加一些操作内容例如释放用到的资源
添加初始化方法和销毁方法
import com.rainsun.Dao.BookDao;public class BookDaoImpl implements BookDao {private BookDaoImpl() {System.out.println(book dao constructor is running);}Overridepublic void save() {System.out.println(Book dao save);}// bean 初始化对应的操作public void init(){System.out.println(init ...);}// bean销毁前的操作public void destroy(){System.out.println(destroy ...);}
}配置文件中添加生命周期控制方法 bean idbookDao classcom.rainsun.Dao.Impl.BookDaoImpl init-methodinit destroy-methoddestroy/但是运行程序后init 方法执行了但是 destroy 方法是没有被执行的 因为 bean 对象是交给 IoC 容器的JVM退出后IoC 容器没有被关闭 bean 对象还没还得及销毁程序已经结束了。
所以我们需要关闭 IoC 容器才能销毁 bean 对象
close 关闭IoC容器 ApplicationContext 接口中没有 close 方法但是其下一个接口 ClassPathXmlApplicationContext 中有 close 方法 改变 IoC 容器的类型调用 close 方法 ClassPathXmlApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);
ctx.close();注册钩子关闭IoC容器
close 关闭容器的方法比较暴力我们可以提前在容器没关闭前设置一个回调函数让JVM在退出的时候回调这个函数完成容器的关闭
回调函数的设置钩子方法
ctx.registerShutdownHook();上面控制bean生命周期的方式比较繁琐不仅需要编写对应的控制方法还需要编写配置文件。
Spring为了简化生命周期的控制提供了两个接口 InitializingBean 和 DisposableBean 重写其中的 afterProperiesSet 和 destroy 方法
package com.rainsun.Service.Impl;import com.rainsun.Dao.BookDao;
import com.rainsun.Dao.Impl.BookDaoImpl;
import com.rainsun.Service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {// 去掉 new 的实现方式改为 DI依赖注入
// private BookDao bookDao new BookDaoImpl();private BookDao bookDao;Overridepublic void save() {System.out.println(Book service save);bookDao.save();}// 通过调用set方法进行依赖注入public void setBookDao(BookDao bookDao) {this.bookDao bookDao;}Override // 属性设置之后也就是属性注入bean对象之后执行public void afterPropertiesSet() throws Exception {System.out.println(service init);}Overridepublic void destroy() throws Exception {System.out.println(service destroy);}
}小结 bean 生命周期控制的方法 编写对象创建后和销毁前方法并在配置文件中为对应bean对象的标签中添加 init-method 和 destroy-method 属性实现 InitializingBean 和 DisposableBean 接口重写其中的 afterPropertiesSet 和 destroy 方法 生命周期控制在Bean整个生命周期的位置 初始化容器 创建对象内存分配执行构造方法执行属性注入set操作执行bean的初始化方法 使用bean 执行业务操作 关闭/销毁容器 执行 bean的销毁方法 关闭容器的方法 调用ConfigurableApplicationContext接口中的方法它是ApplicationContext接口的子类 调用 close() 方法调用回调函数registerShutdownHook() 方法
4 DI 相关
依赖注入描述了容器中建立bean与bean之间的依赖关系的过程bean的运行需要的数据类型有两类引用类型简单类型基本数据类型与String
向类中传递数据有两种方法普通方法set方法构造方法
所以我们可以使用 setter 或者构造器完成简单类型和引用类型的bean注入
4.1 setter 注入
setter 注入引用类型 在类中定义引用类型属性 提供可访问的set方法 在 property 标签的 ref 属性中引用该引用类型的 bean property name ref/setter 注入简单类型 在类中定义简单类型属性 提供可访问的set方法 在 property 标签的 value 属性中注入具体的值 public class BookDaoImpl implements BookDao{private String databaseName;private int connectionNum;public void setDatabaseName(String databaseName) {this.databaseName databaseName;}public void setConnectionNum(int connectionNum) {this.connectionNum connectionNum;}
}Spring 在注入时会自动转换为对应的参数类型 bean idbookDao classcom.rainsun.Dao.Impl.BookDaoImpl init-methodinit destroy-methoddestroyproperty namedatabaseName valuemysql/property nameconnectionNum value10/
/bean4.2 构造器注入
构造器注入引用类型 在类中定义引用类型属性 提供构造方法 在 constructor-arg 标签的 ref 标签引用注入的 bean public class BookServiceImpl implements BookService {private BookDao bookDao; // 1public BookServiceImpl(BookDao bookDao) { // 2this.bookDao bookDao;}
}bean idbookService classcom.rainsun.Service.Impl.BookServiceImplconstructor-arg namebookDao refbookDao/
/bean构造器注入简单类型
同样的定义简单类型属性提供构造方法不同的是这里用 value 属性注入数据
constructor-arg namedatabaseName valuemysql/
constructor-arg nameconnectionNum value10/构造器注入多个数据的耦合问题
对应关系耦合构造函数形参与 标签中的 name 属性对应 解决耦合的方法 方式一按照类型注入使用 type 属性指明类型 constructor-arg typejava.lang.String valuemysql/
constructor-arg typeint value10/如果存在类型相同的参数这种注入方法就存在问题 方式二按照索引下标注入下标从0开始 constructor-arg index0 valuemysql/
constructor-arg index1 value10/解决了参数类型重复的问题但是如果参数顺序发生了变化就带来了新的耦合问题
依赖注入的方式选择
强制依赖使用构造器进行注入。强制依赖是指对象创建过程中必须注入的依赖参数对象而setter注入可能会导致注入null对象可选依赖使用setter注入。可选依赖指对象创建过程中注入的依赖参数对象可有可无Spring提倡使用构造器第三方框架大多使用构造器注入相对严谨我们自己开发用 setter 注入比较简单
4.3 自动配置
上面配置bean依赖的过程很繁琐需要编写配置文件Spring提供了自动配置的方式。
依赖自动装配 IoC 容器根据 bean 所依赖的资源自动在容器中自动查找并注入到bean的过程称为自动装配
自动装配的方式
按类型注入 byType按名称 byName按构造方法不启用自动装配 实现方式 类中定义属性 编写set方法 bean标签中添加autowire属性填写自动注入的方式 public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao bookDao;}
}bean idbookService classcom.rainsun.Service.Impl.BookServiceImpl autowirebyType/注意
注入属性对应的 setter 方法不能省略该属性对应的 bean 对象必须存在在 IoC 容器中被管理如果存在同一类型bean对象则会报错NoUniqueBeanDefinitionException此时可以按照名称注入使用属性 byName该名称是指setter方法去掉set并小写首字母的属性名
自动装配的特征
自动装配只能用于引用类型不能用于简单类型byType 需要保证容器中同类型的bean唯一byName必须保证容器中存在该名称的bean否则注入为 null这里存在耦合自动装配的优先级低于setter注入和构造器注入同时出现时自动装配会失效
4.4 集合注入
需要注入的数据类型
public class BookDaoImpl implements BookDao{private int[] myArray;private ListString myList;private SetString mySet;private MapString, String myMap;private Properties myProperties;public void setMyArray(int[] myArray) {this.myArray myArray;}public void setMyList(ListString myList) {this.myList myList;}public void setMySet(SetString mySet) {this.mySet mySet;}public void setMyMap(MapString, String myMap) {this.myMap myMap;}public void setMyProperties(Properties myProperties) {this.myProperties myProperties;}Overridepublic void save() {System.out.println(Book dao save);System.out.println(遍历数组 Arrays.toString(myArray));System.out.println(遍历List: myList);System.out.println(遍历set: mySet);System.out.println(遍历map: myMap);System.out.println(遍历properties: myProperties);}
}配置文件编写
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdbean idbookDao classcom.rainsun.Dao.Impl.BookDaoImplproperty namemyArrayarrayvalue100/valuevalue200/valuevalue300/value/array/propertyproperty namemyListlistvaluerainsun/valuevaluexiongyuqing/valuevaluesdu/value/list/propertyproperty namemySetsetvaluerainsun/valuevaluexiongyuqing/valuevaluesdu/value/set/propertyproperty namemyMapmapentry keyname valuexyq/entry keyage value23/entry keycity valueqingdao//map/propertyproperty namemyPropertiespropsprop keynamexyq/propprop keyage23/propprop keycityqingdao/prop/props/property/beanbean idbookService classcom.rainsun.Service.Impl.BookServiceImpl autowirebyType/
/beans运行
public class App2 {public static void main(String[] args) {ClassPathXmlApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);BookDao bookDao (BookDao)ctx.getBean(bookDao);bookDao.save();}
}Book dao save
遍历数组[100, 200, 300]
遍历List: [rainsun, xiongyuqing, sdu]
遍历set: [rainsun, xiongyuqing, sdu]
遍历map: {namexyq, age23, cityqingdao}
遍历properties: {cityqingdao, namexyq, age23}List的底层也是通过数组实现的所以list和array标签是可以混用集合中要添加引用类型只需要把value标签改成ref标签这种方式用的比较少
5 IoCDI 配置管理第三方 Bean
5.1 数据源对象管理
实现 Druid 对象的管理 连接数据库创建一个数据库 spring_db pom 文件导入 Druid 的依赖 dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.15/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion6.1.1/version
/dependency在 applicationContext.xml 文件中添加 DruidDataSource 的配置配置第三方 Bean ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
!-- 管理DruidDataSource对象--
bean iddataSource classcom.alibaba.druid.pool.DruidDataSource!-- 数据库驱动设置--property namedriverClassName valuecom.mysql.jdbc.Driver/!-- 数据库连接地址--property nameurl valuejdbc:mysql://localhost:3306/spring_db/!-- 数据库连接用户名--property nameusername valueroot/!-- 数据库连接密码--property namepassword value1234/
/bean
/beans从容器中获取对应的 bean 对象 public class App
{public static void main( String[] args ) {ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);DataSource dataSource (DataSource) ctx.getBean(dataSource);System.out.println(dataSource);}
}Druid 封装了 com.mysql.jdbc.Driver 驱动其他数据源可能没封装需要在pom中导入
5.2 加载 properties 配置文件
数据库连接的哪些地址密码写在Spring配置文件中的不利于后期维护。需要把这些配置信息单独提取出来到 properties 文件中然后从 properties 配置文件中读取属性值来配置bean 在resources 目录下准备一个保存了配置信息的 jdbc.properties文件 jdbc.drivercom.mysql.jdbc.Driver
jdbc.urljdbc:mysql://127.0.0.1:3306/spring_db
jdbc.usernameroot
jdbc.password1234开启 context 命名空间 xmlns:contexthttp://www.springframework.org/schema/context
xsi:schemaLocationhttp://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd“?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd使用context命名空间下的 property-placeholder 标签来加载properties配置文件 context:property-placeholder locationjdbc.properties/使用 ${key} 读取对应属性的内容完成属性注入 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdcontext:property-placeholder locationjdbc.properties/bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName value${jdbc.driver}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//bean
/beans6 核心容器
6.1 容器创建 根据 类路径下的 XML 配置文件创建容器 ApplicationContext ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);根据 文件系统下的XML配置文件创建 ApplicationContext ApplicationContext ctx new FileSystemXmlApplicationContext(D:\\CodeProject\\Java\\SpringFramework\\spring_01_base\\src\\main\\resources\\applicationContext.xml);这样耦合度较高
6.2 获取Bean的方式 根据 id 或者 name 直接获取但是需要进行类型转换 BookDao bookDao (BookDao) ctx.getBean(bookDao);传入bean的名字的同时传入bean的类型 BookDao bookDao ctx.getBean(bookDao, BookDao.class);直接传入 bean 的类型。类似依赖注入的类型注入 BookDao bookDao ctx.getBean(BookDao.class);6.3 容器类的层次结构 可以看出容器的顶层接口是BeanFactory它的常用实现类是 FileSystem/ClassPath XmlApplicationContext BeanFactory是延迟加载只有在获取bean对象的时候才会去创建 ApplicationContext是立即加载容器加载的时候就会创建bean对象 ApplicationContext要想成为延迟加载需要给对应的 bean 添加属性lazy-inittrue bean idbookDao classcom.rainsun.dao.impl.BookDaoImpl lazy-inittrue/