【Spring从入门到出家】1 - 从IOC开始

1 什么是IoC

IoC即控制反转(Inversion of Control),设计模式的一种,不过出现的比较晚,没有被划分到GoF中。

框架的目的就是为了解耦,而IoC作为Spring的基石之一,自然也是为了解耦。那么IoC背后的思想到底是什么呢?

一般,我们对象A需要对象B的时候,我们会通过在对象A内部new一个对象B(对象是引用类型,所以可以看成对象A持有对象B的引用)
在这里插入图片描述如此一来,对象A对对象B存在依赖,当修改对象B的时候,也需要去修改对象A,这样的依赖关系显然是种累赘,给对象A上了层枷锁。

此时,我们不再从对象A中直接new一个对象B了,而是把对象B交给一个容器管理,当对象A需要的时候,这个容器会new一个对象B注入到对象A,这样的话,对象A对对象B的依赖关系就发生了转变。
在这里插入图片描述使用IoC,我们改变了原来依赖对象创建的方式,我们把依赖对象的创建交给了容器。

2 IoC的具体实现——依赖注入

2.1 基于构造器的依赖注入

基于构造器的依赖注入是通过容器调用有参构造器来实现的,每一个参数代表一个依赖。基于构造器的依赖注解和调用一个指定参数的静态工厂方法来创建bean的方法几乎等同。

  1. 无需typeindexname属性
    官网给出了一个案例
package x.y;

public class ThingOne {

    public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
        // ...
    }
}

假设这三个类之间没有继承关系



<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
    </bean>

    <bean id="beanTwo" class="x.y.ThingTwo"/>

    <bean id="beanThree" class="x.y.ThingThree"/>
</beans>
  1. type 属性指明构造器参数类型
    type属性可以让容器去匹配一些简单类型
package examples;

public class ExampleBean {

    // Number of years to calculate the Ultimate Answer
    private int years;

    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
  1. index属性指明构造器参数下标
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

index指定参数下标不仅可以解决相同值所带来的歧义,还可以解决相同类型所带来的歧义。

注意 :index是从0开始的

  1. name属性指定参数名称
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

2.2 基于setter的依赖注入

基于setter方式的依赖注入在调用无参构造器或者无参静态工厂方法实例化bean后,容器再去调用bean中的setter方法来实现。

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

选择基于构造器的依赖注入还是基于setter的依赖注入?
Constructor-based or setter-based DI?
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies.
你会混淆基于构造器的依赖注入和基于setter的依赖注入,对于强制性的依赖项使用构造器,对于可选的依赖项使用setter,这是一个很好的经验法则。
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state.
Spring团队通常提倡构造函数注入,因为它允许您将应用程序组件实现为不可变对象,并确保所需的依赖关系不为空。
此外,构造器注入的组件总是以完全初始化的状态返回给客户端(调用)代码。

  • 实例
  1. 新建一个Address类和Student
public class Address {
    private String address;

	/** Getter Setter */
}
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Set<String> games;
    private Map<String, String> card;
    private String wife;
    private Properties info;
    
	/** Getter Setter */
    
}
  1. 编写基于XML的元数据配置beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="address" class="com.cap.pojo.Address" />

    <bean id="student" class="com.cap.pojo.Student" >
        <!-- 第一种:基本类型 -->
        <property name="name"  value="公孙离" />

        <!-- 第二种:引用类型 -->
        <property name="address" ref="address" />

        <!-- 第三种:数组类型 -->
        <property name="books">
            <array>
                <value>西游记</value>
                <value>水浒传</value>
                <value>红楼梦</value>
                <value>三国演义</value>
            </array>
        </property>

        <!--第四种:list -->
        <property name="hobbies">
            <list>
                <value>听歌</value>
                <value>敲代码</value>
                <value>看电影</value>
            </list>
        </property>

        <!-- 第五种:set -->
        <property name="games" >
            <set>
                <value>LOL</value>
            </set>
        </property>

        <!-- 第六种:map -->
        <property name="card">
            <map>
                <entry key="身份证" value="123123123123123123" />
                <entry key="银行卡" value="1234567890" />
            </map>
        </property>

        <!-- 第7种:null -->
        <property name="wife">
            <null />
        </property>
        
        <!-- 第八种:properties -->
        <property name="info">
            <props>
                <prop key="学号">20200712001</prop>
                <prop key="性别"></prop>
            </props>
        </property>

    </bean>

</beans>
  1. 编写测试方法
public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student);
    }
}
  1. 结果输出为:
Student{
	name='公孙离', 
	address=Address{address='null'}, 
	books=[西游记, 水浒传, 红楼梦, 三国演义], 
	hobbies=[听歌, 敲代码, 看电影], 
	games=[LOL], 
	card={身份证=123123123123123123, 银行卡=1234567890}, 
	wife='null', info={学号=20200712001, 性别=男}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 要从入门到精通Spring,你需要了解Spring框架的基本概念和原理,并学会使用Spring的各个模块。首先,Spring框架是一个轻量级的Java开发框架,主要用于在Java应用程序中实现控制反转(IoC)和面向切面编程(AOP)。Spring框架主要由三个核心模块组成:Spring Core、Spring MVC和Spring Boot。Spring Core是Spring框架的核心,提供了IoC容器和依赖注入功能,它是其他模块的基础。Spring MVC是一种基于Java的Web应用程序开发框架,用于构建灵活和可扩展的Web应用程序。Spring Boot是在Spring基础之上构建的一个扩展,旨在简化开发、测试和部署过程,提供了一种快速搭建应用的方式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spring入门到精通](https://blog.csdn.net/qq_40565874/article/details/124337093)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Spring框架从入门到精通(纯干货,建议收藏)](https://blog.csdn.net/weixin_44006686/article/details/117676003)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [spring入门到精通](https://blog.csdn.net/weixin_51079220/article/details/125833152)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值