6

Spring|IOC的基本理论

 3 years ago
source link: http://cbaj.gitee.io/blog/2021/06/05/Spring%7CIOC%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%90%86%E8%AE%BA/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

Ioc核心理论回顾

在Java中一个对象怎样才可以调用另外一个对象呢,一般会有以下几种方法。

上表可以看到, 引用一个对象可以在不同地点(其它引用者)、不同时间由不同的方法完成。如果B只是一个非常简单的对象 如直接new B(),怎样都不会觉得复杂,比如你从来不会觉得创建一个String 是一个件复杂的事情。但如果B 是一个有着复杂依赖的Service对象,这时在不同时机引用B将会变得很复杂。

无时无刻都要维护B的复杂依赖关系,试想B对象如果项目中有上百过,系统复杂度将会成陪数增加。

IOC容器 的出现正是为解决这一问题,其可以将对象的构建方式统一,并且自动维护对象的依赖关系,从而降低系统的实现成本。前提是需要提前对目标对象基于XML进行声明。

实体Bean的创建

Version:0.9 StartHTML:0000000105 EndHTML:0000000765 StartFragment:0000000141 EndFragment:0000000725

  • 基于Class构建
  • 构造方法构建
  • 静态工厂方法创建
  • FactoryBean创建

1、基于ClassName构建

<bean class="com.tuling.spring.HelloSpring"></bean>

这是最常规的⽅法,其原理是在spring底层会基于class 属性 通过反射进⾏构建。

2、构造方法构建

<bean class="com.tuling.spring.HelloSpring">
<constructor-arg name="name" type="java.lang.String" value="luban"/>
<constructor-arg index="1" type="java.lang.String" value="sex" />
</bean>

如果需要基于参数进行构建,就采用构造方法构建,其对应属性如下:
name:构造方法参数变量名称
type:参数类型
index:参数索引,从0开始
value:参数值,spring 会自动转换成参数实际类型值
ref:引用容串的其它对象

3、静态工厂方法创建

<bean class="com.tuling.spring.HelloSpring" factory-method="build">
<constructor-arg name="type" type="java.lang.String" value="B"/>
</bean>

如果你正在对一个对象进行A/B测试 ,就可以采用静态工厂方法的方式创建,其于策略创建不同的对像或填充不同的属性。
该模式下必须创建一个静态工厂方法,并且方法返回该实例,spring 会调用该静态方法创建对象。

public static HelloSpring build(String type) {
if (type.equals("A")) {
return new HelloSpring("luban", "man");
} else if (type.equals("B")) {
return new HelloSpring("diaocan", "woman");
} else {
throw new IllegalArgumentException("type must A or B");
}
}

4、FactoryBean创建

<bean class="com.tuling.spring.LubanFactoryBean" id="helloSpring123"></bean>

指定一个Bean工厂来创建对象,对象构建初始化 完全交给该工厂来实现。配置Bean时指定该工厂类的类名。

public class LubanFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new HelloSpring();
}
@Override
public Class<?> getObjectType() {
return HelloSpring.class;
}
@Override
public boolean isSingleton() {
return false;
}
}

bean的基本特性

1、作用范围

很多时候Bean对象是无状态的 ,而有些又是有状态的 无状态的对象我们采用单例即可,而有状态则必须是多例的模式,通过scope 即可创建
scope=“prototype”
scope=“singleton”

scope=“prototype
<bean class="com.tuling.spring.HelloSpring" scope="prototype">
</bean>

如果一个Bean设置成 prototype 我们可以 通过BeanFactoryAware 获取 BeanFactory 对象即可每次获取的都是新对像。

2、生命周期

Bean对象的创建、初始化、销毁即是Bean的生命周期。通过 init-method、destroy-method 属性可以分别指定期构建方法与初始方法。

<bean class="com.tuling.spring.HelloSpring" init-method="init" destroy-method="destroy"></bean>

如果觉得麻烦,可以让Bean去实现 InitializingBean.afterPropertiesSet()、DisposableBean.destroy()方法。分别对应 初始和销毁方法

3、加载机制

指示Bean在何时进行加载。设置lazy-init 即可,其值如下:
true: 懒加载,即延迟加载
false:非懒加载,容器启动时即创建对象
default:默认,采用default-lazy-init 中指定值,如果default-lazy-init 没指定就是false

<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"
default-lazy-init="true">

什么时候使用懒加载?
懒加载会容器启动的更快,而非懒加载可以容器启动时更快的发现程序当中的错误 ,选择哪一个就看追求的是启动速度,还是希望更早的发现错误,一般我们会选 择后者。

试想IOC中如果没有依赖注入,那这个框架就只能帮助我们构建一些简单的Bean,而之前所说的复杂Bean的构建问题将无法解决,spring这个框架不可能会像现在这样成功。 spring 中 ioc 如何依赖注入呢。有以下几种方式:

  1. set方法注入
  2. 构造方法注入
  3. 自动注入(byName、byType)
  4. 方法注入(lookup-method)

1、set方法注入

<bean class="com.tuling.spring.HelloSpring">
<property name="fine" ref="fineSpring"/>
</bean>

2、构造方法注入

<bean class="com.tuling.spring.HelloSpring">
<constructor-arg name="fine">
<bean class="com.tuling.spring.FineSpring"/>
</constructor-arg>
</bean>

3、自动注入(byName\byType\constructor)

<bean id="helloSpringAutowireConstructor" class="com.tuling.spring.HelloSpring" autowire="byName">
</bean>

byName:基于变量名与bean 名称相同作为依据插入
byType:基于变量类别与bean 名称作
constructor:基于IOC中bean 与构造方法进行匹配(语义模糊,不推荐)

4、依赖方法注入(lookup-method)

当一个单例的Bean,依赖于一个多例的Bean,用常规方法只会被注入一次,如果每次都想要获取一个全新实例就可以采用lookup-method 方法来实现。

#编写一个抽像类
public abstract class MethodInject {
public void handlerRequest() {
// 通过对该抽像方法的调用获取最新实例
getFine();
}
# 编写一个抽像方法
public abstract FineSpring getFine();
}
// 设定抽像方法实现
<bean id="MethodInject" class="com.tuling.spring.MethodInject">
<lookup-method name="getFine" bean="fine"></lookup-method>
</bean>

该操作的原理是基于动态代理技术,重新生成一个继承至目标类,然后重写抽像方法到达注入目的。前面说所单例Bean依赖多例Bean这种情况也可以通过实现 ApplicationContextAware 、BeanFactoryAware 接口来获取BeanFactory 实例,从而可以直接调用getBean方法获取新实例,推荐使用该方法,相比lookup-method语义逻辑更清楚一些。


Recommend

  • 71
    • zhongfucheng.bitcron.com 6 years ago
    • Cache

    Spring IOC知识点一网打尽!

    Spring IOC知识点一网打尽!

  • 79
    • aodeng.cc 5 years ago
    • Cache

    Spring学习笔记(一):IOC-1

    本作品采用 知识共享署名 4.0 国际许可协议 进行许可。 感谢: Java大联盟...

  • 37
    • www.cnblogs.com 5 years ago
    • Cache

    java~spring-ioc的使用

    spring-ioc的使用 IOC容器在很多框架里都在使用,而在spring里它被应用的最大广泛,在框架层面 上,很多功能都使用了ioc技术,下面我们看一下ioc的使用方法。 把服务注册到ioc容器

  • 23
    • www.cnblogs.com 4 years ago
    • Cache

    Spring IOC 的简单使用

    Spring IOC (Inversion Of Control反转控制容器 一、对于IOC容器的简单理解 在java开发中将程序中的对象交给容器管理,而不是在对象的内部管理。 那么两个简单的问题去分析理解IOC容器 1.为什么叫反...

  • 16
    • segmentfault.com 4 years ago
    • Cache

    Spring IoC 到底是什么

    前言 「<span style="color:orangered;font-weight:bold;">上一篇文章</span>[](

  • 11
    • cbaj.gitee.io 3 years ago
    • Cache

    Spring|IOC原理

    说到spring不得不提其两大特性IOC、AOP,本文主要介绍结合代码看下spring Ioc相关原理,阅读源码如果只是为了看源码效率就会很低,还是要有一定的目的性,我们结合着以下的问题去源码中找答案。本篇文章为《图灵学院》...

  • 12
    • 微信 mp.weixin.qq.com 3 years ago
    • Cache

    Spring 中的 IoC 容器

    概述 对于 Java 后端开发而言,Spring 框架的重要性不言而喻。而 Spring 中最核心的无非就是 IoC 和 AOP。 相关的概念不再赘述,网上可以找到很多对它们的介绍。 这里想说的是,IoC 只是一种设计思想,它...

  • 8
    • 微信 mp.weixin.qq.com 3 years ago
    • Cache

    Spring IoC 容器初始化

    概述 上篇文章「Spring 中的 IoC 容器」从整体介绍了 Spring IoC 容器的相关概念和大致实现流程,本文要进入源码来一探究竟了。 这里仍以前文的代码为例进行分析,测试代码如下: public...

  • 7
    • 微信 mp.weixin.qq.com 3 years ago
    • Cache

    Spring IoC 容器初始化(2)

    前情回顾 前文「 Spring IoC 容器初始化 」...

  • 4

    控制反转 IOC 理论推导 按照我们传统的开发,我们会先去 dao 层创建一个接口,在接口中定义方法。 public interface UserDao { void getUser();} 然后再去实现类中实现这个方法的作用。 public cla...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK