目录
ApplicationContext VS BeanFactory(常⻅⾯试题)
IOC 是Spring框架的核心内容.使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置IOC.
Spring容器在初始化时候先读取配置文件,根据配置文件或者元数据创建与组织对象存入容器中,程序使用的时候再从IOC容器取出需要的对象



了解了 Spring是一个包含众多方法的IOC容器,也知道spring的核心功能就是将对象存放到Spring中,再将对象从Spring中取出来.
接下来我们创建一个Spring项目来实战一下,究竟Spring的IOC思想是怎么回事,怎么创建一个Spring项目,怎么将对象存放到Spring中,又怎么将对象从Spring中取出来..接下来我们逐一讲解.
如何创建Spring项目呢?
我们第一步是创建一个Maven项目



- <dependencies>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-contextartifactId>
- <version>5.2.3.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-beansartifactId>
- <version>5.2.3.RELEASEversion>
- dependency>
- dependencies>
加载之后就会出现相应的jar包

这个就是我们下载的jar包.
这是因为我们引入的这些依赖,还依赖着其他的jar包.
spring-context : spring-context就代表spring本身(spring的上下文)
spring-beans : 代表管理对象的模块(因为我们要往spring里面存bean对象和取bean对象,所以要引入spring-beans依赖 在spring中对象就是bean,(对象会重复使用)).
因为我们现在创建的是Spring core项目,也就是最基础的spring项目,最基础的项目是没有Web模块的,所以需要添加启动类.
而对于Servlet来说,它是一个Web基础,需要配置Tomcat来使用,Servlet是一个Web技术(或者Web框架),它是在Tomcat服务器上运行的,对于Tomcat来说它是内置了启动类,也就是Tomcat源码中会有一个main方法的.
- public class App {
- public static void main(String[] args) {
-
- }
- }
我们创建好一个Spring项目之后..我们如何使用Spring呢??
如何存储呢?? 我们需要以下几步
- /**
- * 创建一个bean对象
- * 就是一个普通的对象
- */
- public class User {
- //就是一个普通的方法
- public void sayHello(){
- System.out.println("hello,spring");
- }
- }
- "1.0" encoding="UTF-8"?>
"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中注册一个bean也就是在配置文件XML中,添加一个bean标签,就代表要往Spring中注册一个bean,至于注册哪一个bean(也就是哪一个类),需要通过bean标签的属性来指定.
- "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 = "user" class = "com.sfx.User">
-
-
- bean>
- beans>
既然我要从spring中取出bean,首先我得先要有一个Spring对象
得到spring上下文对象有两种方式可以获取到 一个是 ApplicationContext 一个是BeanFactory
首先我们来使用ApplicationContext来获取Spring上下文对象
- //1.获取到Spring上下文对象 , 因为我们是从XML文件进行获取Bean的. 要指定从哪个XML获取bean
- ApplicationContext context = //注意这里的配置的XML不要写错了
- new ClassPathXmlApplicationContext("spring-config.xml");

获取bean有很多方式...
通过 bean的id 来获取到Bean对象
- /**
- * 启动类
- */
- public class App {
-
- public static void main(String[] args) {
- //1.获取到Spring上下文对象 , 因为我们是从XML文件进行获取Bean的. 要指定从哪个XML获取bean
- ApplicationContext context = //注意这里的配置的XML不要写错了
- new ClassPathXmlApplicationContext("spring-config.xml");
- //2.获取到bean对象
- //以前获取对象的方式 User user = new User();//在spring中就不要出现了,耦合度高
- //2.1 通过bean的id来获取到bean 通过传入String的参数 id
- //这里需要进行强转
- User user = (User) context.getBean("user");//通过Spring的方式来获取到bean的.
- //3.使用bean 调用bean的方法
- user.sayHello();
- }
-
- }

优点 : 通过 bean的id来获取bean对象的时候,如果有多个bean对象的时候可以通过id来区分我到底是获取哪一个对象.
缺点 : 通过bean的id来获取bean 缺点就是需要进行强转,如果为null的时候就会报异常.
通过 bean的类型来获取bean对象
- public class App {
-
- public static void main(String[] args) {
- //1.获取到Spring上下文对象 , 因为我们是从XML文件进行获取Bean的. 要指定从哪个XML获取bean
- ApplicationContext context = //注意这里的配置的XML不要写错了
- new ClassPathXmlApplicationContext("spring-config.xml");
- //2.获取到bean对象
- //以前获取对象的方式 User user = new User();//在spring中就不要出现了,耦合度高
-
- //2.2通过bean的类型来获取bean
- User user = context.getBean(User.class);
- //3.使用bean 调用bean的方法
- user.sayHello();
- }
-
- }
缺点 : 使用类型来获取bean的缺点就是如果有多个bean对象的时候,就无法进行区分bean了.
通过bean的id + 类型 来获取 bean --->这个是最推荐的做法.
- public class App {
- public static void main(String[] args) {
- //1.获取到Spring上下文对象 , 因为我们是从XML文件进行获取Bean的. 要指定从哪个XML获取bean
- ApplicationContext context = //注意这里的配置的XML不要写错了
- new ClassPathXmlApplicationContext("spring-config.xml");
- //2.获取到bean对象
- //以前获取对象的方式 User user = new User();//在spring中就不要出现了,耦合度高
-
- //2.3通过 bean的 id 和 类型 来获取到bean对象 最稳妥的做法
- User user = context.getBean("user",User.class);
- //3.使用bean 调用bean的方法
- user.sayHello();
- }
- }
通过id获取bean可能出现的异常

当使用 id 来获取 bean对象的时候,需要保证user这个id标识是唯一的.
所以在使用id来获取bean对象的时候,要确保id是唯一的,这时要检查beans标签.--->利用标识可以区分不同的bean.

但使用id来获取bean对象 ,有一个缺点就是如果获取bean为空,在强转就会出现异常.
通过类型来获取bean对象的时候可能会出现的异常

配置文件名写错可能发生的异常

BeanFactory也是一种获取bean的方式.
- public class APP1 {
-
- public static void main(String[] args) {
- //1.获取到Spring上下文对象 , 因为我们是从XML文件进行获取Bean的. 要指定从哪个XML获取bean
- BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
- //2.获取到bean对象
- //以前获取对象的方式 User user = new User();//在spring中就不要出现了,耦合度高
-
- //2.3通过 bean的 id 和 类型 来获取到bean对象 最稳妥的做法
- User user = context.getBean("user",User.class);
- user.sayHello();
-
- }
- }

显然这个是已经是很老的,不推荐使用.
那ApplicationContext 与 BeanFactory的区别是什么呢?
相同点 : ApplicationContext与BeanFactory都是可以获取到Spring上下文对象的.
不同点 :
ApplicationContext 是 BeanFactory 的 一个子类.ApplicationContext具备了BeanFactory的所有功能和能力,BeanFactory只具备了最基础访问Bean的能力,ApplicationContext具有更多的独有的功能,比如国际化支持,资源访问支持等....
BeanFactory是比较老派的类了,由于以前硬件设备和空间不足,所以,BeanFactory按需进行加载,也就是当使用Bean的时候,再去加载,更加轻量,节省资源,缺点是第一次加载Bean比较慢.
而ApplicationContext由于资源充足,采用一直空间来换时间..,它是一次性加载所有的bean(在创建对象的时候就将所有的bean进行初始化创建),所以后面再去访问的时候,就非常的块,性能高.但可能会造成资源的浪费