乐趣区

关于java:惊了这是一篇IOC说明书

大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚!
死鬼~ 看完记得给我来个三连哦!

本文次要介绍 Spring 的全面知识点

如有须要,能够参考

如有帮忙,不忘 点赞

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

说到Spring 你能想到什么?有经验过面试的小伙伴置信都会在面试的时候被问到 “ 谈谈你对 Spring 的了解 ”。

对 Spring 的了解?那不就是个框架嘛,用来简化代码,进步开发效率的。话糙理不糙,事实却是如此。然而想归想,该答复还是得答复。那么 Spring 到底是什么?咱们脑瓜子一闪而过!IOC、AOP 顺口而出,如果你没想到这两个根本的概念,那么预计就得面试等告诉了~

好了,既然 IOC、AOP 都曾经顺口而出了,面试官预计想听的也就这些,你如果扯出什么源码之类的,面试官预计也该冒出冷汗了。

哈哈,说归说,闹归闹,当然具体得看你面试的等级了!当然你有底气将源码讲好,那便是你的能耐了~

能够说不懂 Spring,基本上就能够不必去面试 Java 开发 了。那么面试官问 Spring 会从哪些方面来问你呢?小菜大略整顿如下:

看了这张图,总感觉每个点都晓得,然而让你具体针对某个点进行深讲,又不知从而说起?

Spring 能够说是咱们开发中的外围,咱们从 Spring 能够扩大出了 SpringMVCSpringBootSpringCloud

一篇文章想搞定 Spring 的所有知识点,那有点天方夜谭了,饭要一口一口吃,技术要一点一点学,学好 Spring 那就从 IOC 开始!

IOC 大法

听到 IOC 这个词,如果脑瓜子里没有想到 “ 管制反转 ”,那就阐明你真的不理解 IOC管制反转 不是一门技术,而是一种设计思维。咱们在以往的编程中如果须要一个类,个别是通过 new 的形式来创立一个类对象,而 IOC 的思维便是咱们在 Spring 中只须要定义这个类,而后 Spring 就会主动的帮咱们治理这些类,咱们须要的时候只须要从这个容器获取,而不必通过 new 的形式。

就如同这个,如果咱们想要购买苹果或菠萝,咱们得独自去购买,然而自从水果店的呈现后咱们就不必独自购买,对立从水果店获取即可

如果以上例子不能很好的了解这个概念,咱们能够从代码中剖析:

看完以上的图后,咱们再来了解一下这一段话:IOC 的思维就是反转资源获取的方向,传统的资源查找形式要求组件向容器发动申请查找资源,作为回应,容器适时地返回资源。而利用了 IOC 之后,则是容器被动地将资源推送给他所治理的组件,组件所要做的仅是抉择一种适合的形式来接管资源,这种行为也被称为查找的被动模式。

既然咱们谈到了 IOC 的概念,那就顺便讲下什么是 DI

DIIOC 另一种表述的形式:即组件以一些事后定义好的形式 (setter, construct…) 接管来自容器的资源注入,绝对于 IOC 来说,这种表述更加间接。

看完以上,咱们明确几个概念:

  1. 谁依赖谁?应用程序依赖于 IOC 容器
  2. 为什么须要依赖?应用程序须要 IOC 容器提供对象所须要的内部资源
  3. 谁注入谁?IOC 容器向应用程序注入内部资源
  4. 注入了什么?注入应用程序所须要的内部资源(对象,资源,常量数据等)

㈠ 如何应用

① XML 形式

让咱们来看下案例:

现有对象User

咱们传统获取对象的形式是这样的:

User user = new User();
user.setName("小菜");

这种形式也挺简略,间接通过 new 的形式来创立一个对象,传统也间接。那么在 Spring 外面咱们是怎么样来获取对象的呢?

咱们先创立一个 xml 用来申明 bean,那文件名就叫做 bean.xml 吧,内容如下:

通过 <bean> 标签来申明一个对象,用<property> 来申明对象的属性,获取的形式也比较简单:

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
User user = ac.getBean("user1", User.class);
System.out.println(user);

通过 ApplicationContext 来获取到这个对象,而且这种办法处处皆可用,获取的的对象便是咱们曾经定制好的 User 对象。

通过 <property> 注解申明属性的形式是基于 属性注入 ,在IOC 依赖注入有三种形式:

  • 属性注入
  • 结构器注入
  • 工厂办法注入(较少应用)

属性注入咱们下面曾经见识过了,那咱们再来看下 结构器注入 是怎么一回事

1. 结构器注入

通过这种形式的注入,咱们一样能获取到名称为 小菜User 对象

应用结构器注入的形式,尽管也能很好的提供 Bean 对象,然而如果应用不失当,那也是会踩坑的!小菜本着负责的态度,当然要为小伙伴们指明路线~

咱们当初看下 <constructor-org> 标签外面有哪些属性:

value 咱们曾经应用过了,就是用来示意注入的值

name 就是用来表明对象属性的名称

type 用来表明对象属性的类型

index 用来表明改属性在构造函数中的地位,默认从 0 开始计数

这不就是在说 <constructor-org> 的用法吗,哪里呈现坑了,我看是小菜在坑人才是~ 莫急莫急,坑这就来了!
咱们来看一下新的User 对象:

对象当然没什么问题,该有的构造函数也有。咱们来试一下结构一个 名为小菜,年龄 23 的用户对象吧,一顿操作之下:

<bean id="user3" class="cbuc.life.ioc.User">
    <constructor-arg value="小菜"/>
    <constructor-arg value="23"/>
</bean>

你看上去没啥问题,我看上去也没啥问题,但问题它就来了:

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
User user = ac.getBean("user3", User.class);
System.out.println(user);
/** OUTPUT:
 * User(name= 小菜, salary=23.0)
 */

这尼玛傻眼了,应用的人看到没为年龄赋值,还认为是创立一个 名为小菜,工资 23的用户对象。解决的办法下面也说了,具体怎么用呢?

<bean id="user4" class="cbuc.life.ioc.User">
    <constructor-arg value="小菜"/>
    <constructor-arg value="23" type="int"/>
</bean>

这样就能够防止复制谬误的难堪。如果你跟我说那 salary 也是 int 类型的怎么办,那就能够借助 name

<bean id="user4" class="cbuc.life.ioc.User">
    <constructor-arg value="小菜"/>
    <constructor-arg value="23" type="int" name="age"/>
</bean>

那如果一个构造函数中既有 age 又有 salary,咱们又能够这样做:

public User(String name, int age, int salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
}

这种状况咱们还能够用到 index 这个属性:

<bean id="user5" class="cbuc.life.ioc.User">
    <constructor-arg value="小菜"/>
    <constructor-arg value="23" index="1"/>
    <constructor-arg value="2000" index="2"/>
</bean>

这样子咱们就能够获取到想要的 User 对象了:

User(name= 小菜, age=23, salary=2000)

唉,真麻烦,用这种形式创立进去的对象还不如我 new 进去的香。登时对 Spring 产生了质疑的态度

等等等等,贴心的小菜又来了,简略给你说下另外一种创立的办法,那就是借助 注解 的形式。真是个渣男,用到时候美滋滋,创立的时候就埋怨这埋怨那的~ 曾经给你提前剧透还有注解的形式了,那就让小菜把剩下的 XML 讲完吧,毕竟小菜绝不始乱终弃,拒做渣男~

2. 字面值

XML 的应用中还反对 字面值 的应用,你要问我什么是 字面值?那咱们只能问你在 Mybatis 的 xml 配置文件中有没有见过<![CDATA[<Value>]] 这种写法,你要是还跟我说没有,那小菜就要思考是否再出一期 Mybatis 的解说了~ 话不多说,先看应用吧:

咱们来创立一个名为 Cbuc.~!<> 的非凡用户,这么非凡的名称那必定得用非凡的形式了

后果是胜利创立也胜利获取了~

3. 外部 Bean

什么是外部类,那就是我私生的孩子不想让他人发现!当然有时候也能够让他人发现~ 然而如果我在 XML 创立的过程中创立的类不想被人援用该怎么办,那当然也是有的办了:

简略发现三件事,第一件:对象胜利创立也胜利获取了 ( 废话 ) 第二件:<bean> 的建设是在 <property> 属性里的( 这才合乎外部类 ) 第三件:<bean> 外部建设没有ID 这个属性( 都不想让他人援用,要 ID 有何用)

如果你不想本人创立一个 Address 对象,而是想要他人的,而后本人再改一改也能用,这简略也说就是想白嫖,尽管说也行~

用技术能够白嫖,学技术不可白嫖

关注 VX:小菜良记

每篇都是初恋的滋味~

4. 汇合属性赋值

除了下面咱们能够给根本类型和String 赋值之外,还能够给 List/Map 这些赋值,用法如下:

咱们在 User 类中增加了几个新属性:

private List<String> phoneList;

private List<Address> addressList;

private Map<String, String> animalMap;

如果你感觉包一层<property> 有写碍事,那么也不要紧,尽量满足你的要求!p 命名空间 它来了~

只管对汇合属性不好复制也能够借助 <util:map /><util:list /> 来帮忙。真是 Spring 一点一点变好,而你一点一点变渣 ,当初是不是脑子还想着怎么应用 注解 的形式来开发~

你认为完结了,却只是过半!通过 XML 咱们甚至能够看到继承关系,惊不惊喜意不意外~

5. Bean 的继承

咱们间接通过 parent 属性来指明父类对象,而后再给本人其余属性赋值。说到这里,咱们就再提一嘴,有一个 abstract 属性,看单词就晓得形象的意思,然而却起到 Java接口 的作用,用途便是增加这个属性并设为 true,那么它的工作就是专门 “生孩子”,也就是变成了一个 配置模板,只能作为其余 Bean 的模板,而不能被 Spring 实例化。

配置了这个属性,咱们要再想通过 Spring 容器获取,就会抛出以下谬误:

6. 生命周期

如果咱们有点属性 Bean 的生命周期,那么应该对 initdestory 两个办法有些相熟,那就是在 Bean 创立和销毁的时候执行的办法,咱们同样能够在 XML 配置 Bean 的时候指出。

User 对象中咱们有个 initMethod()destroyMethod() 办法,而后在构建 Bean 的时候指明:

而后从控制台中能够看到初始化办法执行了:

讲到这里XML 的配置形式也讲的差不多了,那就如你所愿,看看注解的形式吧~

② 注解形式
1. @Configuration

通过注解的形式创立 Bean,咱们须要用到两个注解@Configuration@Bean,用法如下:

创立一个BeanConfig 的配置类,而后通过 AnnotationConfigApplicationContext 获取该类

这种办法就很美滋滋,去取了 XML文件的配置,感觉不便了不少,嘴角也露出迷人的微笑。

注解的形式简略而弱小,让人不胜向往!接下来欢送来到注解新天地,向导小菜~

咱们在下面见识到了 @Configuration@Bean 两个注解,这两个注解的应用帮咱们很好的构建和获取 bean 的过程。那咱们就从意识这两个注解开始!

@Configuration & @Bean

这个注解用在类上,作用于 xml 配置文件统一,向 Spring 表明这是一个配置类。配合 @Bean 能够初始化自定义 Bean

那咱们有时候会不会只想要一个默认的 Bean,不须要定制化,当然用下面的形式咱们也能很好的实现:

@Configuration
public class BeanConfig {
    @Bean
    public User getDefaultUser() {return new User();
    }
}
2. @ComponentScan

然而如果一两个 Bean,咱们这样子做还能够承受,当 Bean 的数量多起来预计又会埋怨了~

解决办法又来了,那就是 包扫描 ,何为 包扫描 ?那就是咱们扫描指定包下的实体类,而后将其注册到 Spring 容器中,这个办法切实是秒啊~ 那如何实现呢?借助@ComponentScan 注解:

该有的注解 @ComponentScan 有了,然而如同还有个生疏的注解 @Component。其实这里不止能够用 @Component 还能够用 @Controller、@Repository、@Service … 这些注解,这些注解的共同点就是把标记了这些注解的类纳入 Spring 容器中进行治理。然而单单标记这些注解还不够,还须要咱们下面说的 @ComponentScan 这个注解的配合,它通知 Spring 哪个 packages 下用注解标识的类会被 spring 主动扫描并且装入 bean 容器。

ComponentScan是个弱小的注解,咱们一起看下这个注解外面有哪些属性:

  • basePackages:指明要扫描的包
  • excludeFilters = Filter[] :指明扫描的时候依照什么规定来排除其余组件
  • includeFilters = Filter[]:指明扫描的时候依照什么规定来只获取须要的组件

从上图中咱们能够看到这个注解的简略用法,咱们想要的后果是注入cbuc.life.ioc 包下的应用注解@Component 标注的类,如果应用@Controller 注解标注的类,则不注入。

Filter 中咱们还看到一个枚举类:FilterType,外面有这些属性:

  • FilterType.ANNOTATIONl:依照注解
  • FilterType.ASSIGNABLE_TYPE:依照给定的类型
  • FilterType.ASPECTJ:依照 ASPECTJ 表达式
  • FilterType.REGEX:依照正则表达式
  • FilterType.GUSTOM:依照自定义规定

这里咱们重点意识下 FilterType.GUSTOM 这个过滤定义规定,它反对咱们自定义过滤规定,自定的规定类须要实现TypeFilter

通过这个咱们自定义的规定,能够完满的将 Person 这个类放入 Spring 容器中,而 UserController 这个类却没有搁置。

如果咱们须要定义多个 @ComponentScan,咱们能够借助@ComponentScans 将它们组合起来:

@ComponentScans(value = {@ComponentScan(),@ComponentScan()})
3. @Scope & @Lazy

咱们在 User 对象的构造函数中写上这样一行代码,示意被应用的时候,会提醒咱们它被创立了:

public User() {System.out.println("User 对象被创立了");
}

当咱们在代码中应用它的时候:

@Configuration
@ComponentScan(basePackages = "cbuc.life.ioc")
public class BeanConfig {
    @Bean
    public User getUser() {User user = new User();
        user.setName("小菜");
        user.setAge(23);
        user.setSalary(2000);
        return user;
    }

    public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
    }
}

这个时候咱们在控制台看到的内容是这样的:

这阐明了什么?阐明了 IOC 容器启动后会调用办法创建对象放到 IOC 容器中,当前每次获取都是间接从容器中拿。那么相当于在程序的整个生命周期中,每个中央用到的 Bean 都是同一个!这种称为单例模式。单例模式的益处置信大家也不生疏,最不言而喻的有点便是节约了系统资源,不须要频繁创立爱你和销毁对象。然而有些状况下咱们不想要单例模式,那种时候,Spring 当然也反对你批改 Bean 的作用域!那就是借助 @Scope 注解。咱们先晓得一下 Spring 中存在几种 Bean 的作用域,能力更好的切换~

  • singleton:bean 在每个 SpringIOC 容器中都只有一个实例(默认作用域)
  • protorype:一个 bean 的定义能够有多个实例
  • request::每次 http 申请都会创立一个 bean。该作用域仅在基于 web 的 Spring ApplicationContext 情景下无效
  • session:在一个 http session 中,一个 bean 定义对应一个示例。该作用域仅在基于 web 的 SpringApplicationContext 情景下无效
  • global-session:在一个全局的 http session 中,一个 bean 定义对应一个示例。该作用域仅在基于 web 的 SpringApplicationContext 情景下无效

存在了 5 中作用域,如果咱们想要切换作用域,那么只须要在 @Scope 上指明即可:

应用了 prototype 这种形式,IOC 容器启动的时候不会创建对象,只用当应用到的时候才会创建对象

在单例中,有一种懒汉式加载,这里当然也是反对的,只需一个 @Lazy 注解

这样子只管应用的单例模式,然而 IOC 容器启动时也不会创建对象,只有须要的时候才会创立

4. @Conditional

condition 的意思是条件,那么这个注解的用途便是 依照肯定的条件进行判断,满足条件后再给容器中注册 Bean

这里简略写个例子,

MyCondition

应用

通过这种形式,如果是 windows 操作系统则注入 User 对象,反之不注入。

5. @Import

咱们回顾一下给容器中注册组件的几种形式,闭眼想一想~ 好了,小菜来给你温习一下:

  • 包扫描 + 组件标注注解(@Controller、@Service、@Repository、@Component)
  • 在配置类中通过 @Bean 注册

除了下面的两种,我晓得你是难以满足的,那么就再来一种!那就是 @Import 的形式

应用形式有三种,上面咱们一一介绍:

1)@Import(要导入到容器中的组件)

2)ImportSelector(返回须要导入的组件的全类名数组)

咱们须要编写自定义的 ImportSelector

而后在@Import 注解中引入:

3)ImportBeanDefinitionRegistrar(手动注册 bean 到容器中)

这个类就比拟有意思,有些因果的滋味~ 同样的咱们须要自定义 ImportBeanDefinitionRegistrar

而后在@Import 注解中引入:

通过下面 3 种 @Import 的用法,是否意识到了 Spring 的弱小,它好像处处为咱们着想,咱们想要的不想要的,它全都有!

别急!还有~

6. @Value

这个注解是给参数赋值的,用几种比拟弱小的用法:

  • 根本数值赋值
  • 反对 SPEL 写法
  • 能够用 ${} 取出配置文件中的值

7. @Autowired & @Qualifier

此注解用于 bean 的 field、setter 办法以及构造方法上,显式地申明依赖。

默认优先依照类型去容器中找对应的组件:applicationContext.getBean(User.class),如果找到多个雷同类型的组件,就会将属性的名称作为组件的 ID 再去容器中查找:applicationContext.getBean("user"),咱们也能够应用 @Qualifier 来指定拆卸组件的 ID,而不是应用属性名:

@Autowired 主动拆卸的时候默认肯定要将属性赋好值,否则就会报错。不过咱们能够应用required = false 让主动拆卸容许应用空拆卸:

@Autowired(required = false)
@Qualifier("userController")
private UserController userController;

用于 Field 上:

@Component
class Book{
    @Autowired
    private Address address;
}

用于 setter()办法上:

@Component
class Book{
    private Address address;

    @Autowired
    public void setAddress(Address address) {this.address = address;}
}

用于 构造函数 上:

@Component
class Book{
    private Address address;

    public Book(Address address) {this.address = address;}
}

这种形式须要留神的是一个类中只容许有一个构造方法应用此注解。此外,在 Spring4.3 之后,如果一个类仅仅只有一个构造方法,那么即便不应用此注解,Spring 也会主动注入相干的 Bean

8. @Profile

Spring 为咱们提供@Profile,能够指定组件在哪个环境的状况下能力被注册到容器中

  1. 加了环境标识的 bean,只有这个环境被激活的时候能力注册到容器中。默认是 default 环境
  2. 写在配置类上,只有是指定的环境的时候,整个配置类外面的所有配置能力开始失效
  3. 没有标注环境标识的 bean, 在任何环境下都是加载的

㈡ IOC 容器

下面如何应用是讲的差不多了,你学到了多少呢~ 那你在学的过程中有没有一个问号始终在。那就是为啥能通过 ApplicatinContext 来获取到 Spring 中构建的 Bean 呢?。

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
User user = ac.getBean("user4", User.class);

IOC 容器其实就是一个大工厂,它用来治理咱们所有的对象以及依赖关系

原理简略来说就是三步:

  • Ⅰ:通过 Java 反射技术获取类的所有信息
  • Ⅱ:再通过配置文件(XML) 或 注解(Annoation) 来形容类与类之间的关系
  • Ⅲ:联合下面两步获取到的信息就能够构建出对应的对象之间的依赖关系

在 Spring IOC 容器读取 Bean 的配置创立 Bean 之前,必须对它进行实例化,只有在容器实例化后,才能够从 IOC 容器外面获取到 Bean 实例并应用。

那么 Spring 中提供了两种类型的 IOC 容器实现:

  • BeanFactory:IOC 容器的根本实现
  • ApplicationContext:提供了更多的高级个性,是 BeanFactory 的子接口

BeanFactory 是 Spring 框架的基础设施,面向 Spring 自身,ApplicationContext 是面向 Spring 框架的开发者,简直所有的利用场景都间接用 ApplicationContext 而非底层的 BeanFactory

通过继承图能够看到 ApplicationContext 又有两个子类 ClassPathXmlApplicationContextAnnoationConfigApplicationContext,当然理论远远不止这些,咱们下面用 XML 的形式是用到 ClassPathXmlApplicationContext,而用注解的形式是用到 AnnoationConfigApplicationContext

那么为什么应用 ApplicationContext 而不是 BeanFactory,咱们就先来看看两者的区别:

  • ApplicationContext 可能利用反射技术自动识别出配置文件中定义的 BEANPostProcessor、InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor,并主动将它们注册到利用上下文中,而 BeanFactory 须要在代码中通过手动调用 addBeanFatoryPostProcessor()办法进行注册。
  • ApplicationContext 在初始化利用上下文的时候就实例化了所有但实例的 Bean,而 BeanFactory 在初始化容器的时候并为实例化 Bean,直到第一次拜访某个 Bean 时才实例化指标 Bean

那么咱们能够持续看下 Bean 的初始化过程:

㈢备战面试

以上那些内容置信曾经为你储备了不少常识干粮了,对于开发,对于面试,置信你也曾经跃跃欲试了!既然曾经筹备好了,那咱们就进入面试环节!

管制反转 (IOC) 有什么用?

  • 治理对象的创立和依赖关系的保护
  • 解耦,由容器器保护具体的对象
  • 托管了类的产生过程

IOC 的长处是什么?

IOC 或依赖注入把利用的代码降到最低,它使利用更加容易测试,单元测试不再须要单例和 JNDI 查找机制。以最小的代价和最小的侵入性使涣散耦合得以实现。IOC 容器反对加载服务时以 懒汉式 饿汉式 加载。

IOC 容器拆卸 Bean 有几种形式?4 种!

  • XML 配置
  • 注解配置
  • JavaConfig
  • 基于 Groovy DSL 配置(少见)

依赖注入有几种形式?3 种!

  • 属性注入(通过 setter() 办法)
  • 构造函数注入
  • 工厂办法注入

Bean 有几种作用域?5 种!

  • singleton:bean 在每个 SpringIOC 容器中都只有一个实例(默认作用域)
  • protorype:一个 bean 的定义能够有多个实例
  • request::每次 http 申请都会创立一个 bean。该作用域仅在基于 web 的 Spring ApplicationContext 情景下无效
  • session:在一个 http session 中,一个 bean 定义对应一个示例。该作用域仅在基于 web 的 SpringApplicationContext 情景下无效
  • global-session:在一个全局的 http session 中,一个 bean 定义对应一个示例。该作用域仅在基于 web 的 SpringApplicationContext 情景下无效

Spring 中有几种主动拆卸形式?5 种

  • no:默认的形式是不进行主动拆卸的,通过手工设置 ref 属性来进行拆卸 bean。
  • byName:通过 bean 的名称进行主动拆卸,如果一个 bean 的 property 与另一 bean 的 name 雷同,就进行主动拆卸。
  • byType:通过参数的数据类型进行主动拆卸。
  • constructor:利用构造函数进行拆卸,并且构造函数的参数通过 byType 进行拆卸。
  • autodetect:主动探测,如果有构造方法,通过 construct 的形式主动拆卸,否则应用 byType 的形式主动拆卸。

@Autowired 注解有什么作用

  • 默认是依照类型拆卸注入的,默认状况下它要求依赖对象必须存在(能够设置它 required 属性为 false)。
  • 提供了更细粒度的管制,包含在何处以及如何实现主动拆卸。能够润饰 setter 办法、结构器、属性等。

@Autowired 和 @Resource 之间的区别

  1. @Autowired 可用于:构造函数、成员变量、Setter 办法
  2. @Autowired 默认是依照类型拆卸注入的,默认状况下它要求依赖对象必须存在(能够设置它 required 属性为 false)
  3. @Resource 默认是依照名称来拆卸注入的,只有当找不到与名称匹配的 bean 才会依照类型来拆卸注入

Spring 中 Bean 的生命周期

  1. Spring 容器从 XML 文件中读取 Bean 的定义,并实例化 Bean
  2. Spring 依据 Bean 的定义填充所有属性
  3. 如果 Bean 实现了 BeanNameAware 接口,Spring 将传递 Bean 的 ID 到 setBeanName ()办法中
  4. 如果 Bean 实现了 BeanFactoryAware 接口,Spring 将传递 beanFactory 到 setBeanFactory() 办法中
  5. 如果有和 Bean 相关联的 BeanPostProcessors,Spring 会在 postProcesserBeforeInitialization() 办法内调用他们
  6. 如果 Bean 实现了InitializingBean,会调用它的 afterPropertySet() 办法,如果 Bean 申明了初始化办法,那么会调用此办法
  7. 如果有BeanPostProcessors 和 Bean 关联,那么会调用这些 Bean 的 postProcesserAfterInitialization() 办法
  8. 如果 Bean 实现了 DisposableBean,它将调用 destroy() 办法

ApplicationContext 和 BeanFactory 的区别

  • BeanFactory能够称为 低级容器。它比较简单,能够了解为就是一个 HashMap,key 是 BeanName,Value 就是 Bean 实例。通常只提供注册(put) 和 获取(get) 这两个性能。
  • ApplicationContext 能够称为 高级容器。它过继承了多个接口,因而多了更多的性能。例如资源的获取,反对多种音讯(例如 JSP tag 的反对),对 BeanFactory 多了工具级别的反对期待,它 代表着整个大容器的所有性能。该接口定义了一个 refresh() 办法,用于刷新整个容器,即从新加载 / 刷新所有的 bean。

ApplicationContext 的通常实现是什么?

  • FileSystemXmlApplicationContext:此容器从一个 XML 文件中加载 bean 的定义,咱们须要提供 Bean 配置文件的全路径名给它的构造函数
  • ClassPathXmlApplicationContext:此容器也从一个 XML 文件中加载 beans 的定义,这里,你须要正确设置 classpath 因为这个容器将在 classpath 里找 bean 配置
  • WebXmlApplicationContext:此容器加载一个 XML 文件,此文件定义了一个 WEB 利用的所有 bean

END

对于 Spring 中的 IOC 相干常识就到这里完结啦,不晓得小伙伴们看的过不过瘾。不过瘾的小伙伴连忙关注点起来,下一篇 AOP 给你安顿上!

路漫漫,小菜与你一起求索!

明天的你多致力一点,今天的你就能少说一句求人的话!

我是小菜,一个和你一起学习的男人。 ????

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

退出移动版