Spring IoC容器与Bean管理(三)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Spring IoC容器与Bean管理

6.对象依赖注入


本节,我们来学习如何在spring IoC容器中设置对象的依赖关系。这个过程我们称为依赖注入。依赖注入说白了就是将两个对象关联起来。


依赖注入是指运行时将容器内对象利用反射赋值给其他对象的操作。


利用setter实现静态数值注入


585d1dcf172e4a92a95202475e037ef2.png


这个bean,里面包含的属性一律采用property这个标签来指代。property标签最基础的有2个属性,第一个是name,指属性名,第二个是value,指属性值。在创建好这个bean以后,便会通过反射机制调用各属性的setter方法来动态设置数值。


13d9ef9d66584e329b8f6e8d95815f98.png


基于构造方法注入对象


d0a8357473584bab9cb6a263ecc3bded.png


注入集合对象


前面写的注入对象都是单个对象,这一节我要讲解List或Set等这样的集合对象注入。注意各标签的大小写。


6434c92b8d344f2ea676d1fff974176d.png


可以用value标签来设置具体的数值,或者ref引入具体的bean。


0f7148bc00474ea59a3e7eb07b7541d4.png


list和set的区别是list里面的元素不允许出现重复,而set里面的元素可以出现重复。


046b750fcef84243990dc1ce9c6608e6.png

e0c083b6536a40ae84cf60ce14424d8b.png


properties只允许key和value是字符串类型的。


下面是一个样例:


   <bean id="company" class="com.haiexijun.ioc.entity.Company">
        <property name="rooms">
            <list>
                <value>201-总裁办</value>
                <value>202-总经理办公室</value>
                <value>203-研发部会议室</value>
                <value>203-研发部会议室</value>
            </list>
        </property>
        <property name="computers">
            <map>
                <entry key="dev-112" value-ref="computer1"></entry>
                <entry key="dev-113">
                    <bean class="com.haiexijun.ioc.entity.Computer">
                            <constructor-arg name="brand" value="联想"/>
                            <constructor-arg name="price" value="2222"/>
                            <constructor-arg name="sn" value="12312412"/>
                            <constructor-arg name="type" value="台式机"/>
                    </bean>
                </entry>
            </map>
        </property>
        <property name="info">
            <props>
                <prop key="phone">13214124</prop>
                <prop key="address">zjian</prop>
            </props>
        </property>
    </bean>
    <bean id="computer1" class="com.haiexijun.ioc.entity.Computer">
        <constructor-arg name="brand" value="联想"/>
        <constructor-arg name="price" value="2222"/>
        <constructor-arg name="sn" value="12312412"/>
        <constructor-arg name="type" value="台式机"/>
    </bean>

这里就不作过多的解释了。


查看容器内对象


前面学习了如何在容器内创建对象,以及设计对象的关系。但是所有这些信息都是通过脑补来完成的。如果一个工程越来越大,

对象越来越多,那我们如何知道当前容器中到底有多少对象,这些对象又是什么类型呢?

可以通过ApplicationContext对象的getBeanDefinitionNames()方法获取到bean的名字的String数组。通过类对象.getClass().getName()来获取全类名,如context.getBean(beanName).getClass().getName()。如果要获取实体类具体的内容,用实体类对象.toString() 方法。


7.Bean对象的作用域及生命周期


bean scope属性详解


scope的原意是范围的意思。


bean scope属性用于决定对象何时被创建与作用的范围。通过设置 scope属性会影响到容器内对象的数量。默认情况下bean会在IoC容器创建后自动实例化,全局唯一。


a7b1923bda0b4fd496157b947a77d37a.png

24331c78477c4eeb84cfadee41d73648.png

下面是singleton单例示意图

单例的执行效率高,不用多次创建同一个对象,但也会引发很多线程安全问题。


c97e0ad1285d425b99916e9c41de457b.png


下面是prototype多例示意图:


f97bccf973bf439297594279278e8139.png


singleton 与 prototype对比:


16e4cb024eec4424929fb0ad58ab8f90.png


IoC的生命周期


987dc55002b8449fa798a6ea41f2b733.png


下面写一个案例来演示IoC的生命周期:


配置好了项目后,创建一个entity实体类,名为Order:

package com.haiexijun.ioc.entity;
public class Order {
    private Float price;
    private Integer quantity;
    private Float total;
    public Order(){
        System.out.println("创建Order对象"+this);
    }
    public void init(){
        System.out.println("执行Init方法");
        total=price*quantity;
    }
    public void destroy(){
        System.out.println("销毁容器,释放Order对象相关的资源");
    }
    public void pay(){
        System.out.println("订单金额为:"+total);
    }
    public Float getPrice() {
        return price;
    }
    public void setPrice(Float price) {
        System.out.println("设置price:"+price);
        this.price = price;
    }
    public Integer getQuantity() {
        return quantity;
    }
    public void setQuantity(Integer quantity) {
        System.out.println("设置quantity:"+quantity);
        this.quantity = quantity;
    }
    public Float getTotal() {
        return total;
    }
    public void setTotal(Float total) {
        this.total = total;
    }
}


然后在applicationContext.xml文件中编写bean


<?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="order1" class="com.haiexijun.ioc.entity.Order" init-method="init" destroy-method="destroy">
        <property name="price" value="19.8"/>
        <property name="quantity" value="1000"/>
    </bean>
</beans>


会发现,我并没有在bean中为total属性设置属性和属性值,而是通过init-method属性指定order类里面的init方法来计算total来设置total属性的。我们还定义了一个destroy-method的属性,用于指定IoC容器被销毁后执行的方法,一般用于释放与该对象关联的资源。


最后编写代码运行:


package com.haiexijun.ioc;
import com.haiexijun.ioc.entity.Order;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringApplication {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        System.out.println("====IoC容器以初始化完成====");
        Order order= context.getBean("order1", Order.class);
        order.pay();
        //销毁容器,会自动调用xml中设置的destroy-method方法
        ((ClassPathXmlApplicationContext)context).registerShutdownHook();
    }
}

运行结果如下:


ac1b7ef80b1e4033ae65169089355ad0.png

相关文章
|
20天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
28天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
19天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
31 0
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
73 0
|
2月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
48 0
|
7月前
|
XML Java 数据格式
Spring IoC容器初始化过程(xml形式)
Spring IoC容器初始化过程(xml形式)
82 0
|
7月前
|
XML Java 数据格式
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
69 1
|
XML Java 数据格式
Spring源码阅读-IOC容器初始化过程
Spring IOC容器的初始化过程:Resource定位,BeanDefinition载入,向IOC容器注册BeanDefinition。整个过程由refresh()方法触发,三个过程由不同的模块完成,使用户更加灵活的对这三个过程剪裁和扩展。
156 0
|
XML JavaScript Java
Spring IoC容器初始化过程(xml形式)
Resource是Spring中用于封装I/O操作的接口,在创建Spring的容器的时候,会根据xml对应配置的类型,加载不同的数据类型
79 0

热门文章

最新文章

下一篇
无影云桌面