Spring全家桶(二)Bean之间的关系、自动装配、作用域和使用外部文件

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 五、Bean的自动装配Spring IOC容器可以自动装配Bean,需要在bean的autowire属性里指定自动装配的模式。

五、Bean的自动装配

Spring IOC容器可以自动装配Bean,需要在bean的autowire属性里指定自动装配的模式。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="address" class="com.stuspring.autowire.Address"
          p:city="BeiJing" p:street="HuiLongGuan">
    </bean>

    <bean id="car" class="com.stuspring.autowire.Car" p:brand="AuDi"
          p:price="400000">
    </bean>

    <bean id="car2" class="com.stuspring.autowire.Car" p:brand="AuDi"
          p:price="400000">
    </bean>
    <bean id="person1" class="com.stuspring.autowire.Person" p:name="Tom"
          p:address-ref="address" p:car-ref="car"/>

    <!--使用autowire属性指定自动装配的方式
       byName 根据bean的id和bean的setter风格属性进行自动装配,如果有匹配的,则自动装配。
       byType 根据类型自动装配。car和car2都满足,byType会报错。
       确定:不够灵活,实际开发中很少使用自动装配。
    -->
    <bean id="person2" class="com.stuspring.autowire.Person" p:name="Lily"
          autowire="byName">
    </bean>

</beans>

六、Bean之间的关系

6.1 Bean的继承关系

一个Address类,有city和Street 2个属性。

package com.stuspring.relation;

/**
 * Created by bee on 17/4/25.
 */
public class Address {

    private String city;
    private String street;
    //省略setter、getter和toString方法
}

配置2个Bean:

  <bean id="address" class="com.stuspring.relation.Address"
          p:city="BeiJing" p:street="WuDaoKou"/>
    <bean id="address2" class="com.stuspring.relation.Address"
          p:city="BeiJing" p:street="XiZhiMen"/>

address2和address除了street属性不一样,其他都相同,可以使用bean的集成属性来简化配置:

    <bean id="address" class="com.stuspring.relation.Address"
          p:city="BeiJing" p:street="WuDaoKou"/>
    <bean id="address2" p:street="XiZhiMen" parent="address"/>
  1. Spring允许继承bean的配置,被继承的bean称为父bean,继承父bean的bean称为子bean。

  2. 子bean从父bean中继承配置,包括bean的属性配置

  3. 子bean也可以覆盖父bean继承过来的配置

  4. 父bean可以作为配置模板,也可以作为bean的实例。若只想把父bean作为模板,可以设置<bean>的abstract属性为true,这样spring就不会实例化这个bean

  5. 可以忽略父bean的class属性,让子bean指定自己的类,共享相同的配置,此时abstract属性必须为true。

抽象bean例子:

    <bean id="address" class="com.stuspring.autowire.Address"
          p:city="BeiJing" abstract="true"/>

    <bean id="address2" p:street="XiZhiMen" parent="address"/>

<!-- 覆盖父bean的配置-->
    <bean id="address3" p:city="NanJing" p:street="DaFengChang"
          parent="address"/>

忽略父bean的class属性:


    <bean id="address" p:city="BeiJing^"  p:street="XiZhiMen" abstract="true"/>

    <bean id="address2"  class="com.stuspring.autowire.Address"  parent="address"/>
    <!-- 覆盖父bean的配置-->
    <bean id="address3"  class="com.stuspring.autowire.Address" p:city="NanJing" p:street="DaFengChang"
          parent="address"/>

6.2 Bean的依赖关系

Spring允许用户通过depends-on属性设定bean前置的依赖bean,前置依赖的bean会在本bean实例化之前创建好。

如果前置依赖多个bean,可以通过逗号、空格的方式配置bean的名称。

    <bean id ="car" class="com.stuspring.autowire.Car" p:brand="Ford"
          p:price="200000"/>

    <bean id="person" class="com.stuspring.autowire.Person"
          depends-on="car"/>

bean person依赖car,car不存在person无法实例化。

七、Bean作用域

定义一个bean:

    <bean id="car" class="com.stuspring.autowire.Car"/>

测试:

  ApplicationContext ctx=new ClassPathXmlApplicationContext
                ("beans-scope.xml");
  Car car1= (Car) ctx.getBean("car");
  Car car2= (Car) ctx.getBean("car");
  System.out.println(car1==car2);

打印结果:

true

car1和car2是同一个对象。

把作用域改为prototype:

<bean id="car" class="com.stuspring.autowire.Car" scope="prototype"/>

再次比较car1和car2,运行结果:

false

作用域改成prototype后,car1和car2不再是同一个对象。

在Spring中,可以在<Bean>元素的scope属性里设置Bean的作用域,默认情况下Spring只为每个在IOC容器中声明的Bean创建唯一一个实例,整个IOC容器范围内都能共享该实例。

类别 说明
singleton 在Spring的IOC容器中仅存在一个Bean实例,以单例的方式存在
prototype 每次调用getBean()都会返回一个新的实例
request 每次Http请求都会创建一个Bean,该作用域仅适用于WebApplicationContext属性
session 同一个HTTP SESSION共享一个BEAN,不同的HTTP SESSION使用不同的BEAN。该作用域仅适用于WebApplicationContext属性。

八、使用外部属性文件

配置文件里配置Bean时,有时需要在Bean的配置里混入系统部署的细节信息,比如文件路径、数据源配置信息等,这些部署细节需要和Bean配置相分离。
Spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器,这个处理器允许用户将Bean配置的部分内容外移到属性文件中。在Bean配置文件里使用形式为${var}的变量,PropertyPlaceholderConfigurer从属性文件里加载属性并使用这些属性来替换变量。

    <bean id="dataSource"
          class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///blog"/>
    </bean>

测试:

package com.stuspring.properties;

import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by bee on 17/4/25.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext
                ("beans-properties.xml");
        DataSource dataSources= (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSources);
    }
}

resource目录下新建db.properties,写入连接数据库的配置信息:

jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull

在Spring Bean的配置文件中引入context命名空间。重新配置:

    <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClass" value="${jdbc.driverClassName}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
    </bean>

测试连接是否成功:

 ApplicationContext ctx=new ClassPathXmlApplicationContext
                ("beans-properties.xml");
 DataSource dataSource= (DataSource) ctx.getBean("dataSource");
 DataSource dataSource2= (DataSource) ctx.getBean("dataSource2");
 System.out.println(dataSource);
 System.out.println(dataSource2);
 Connection conn=dataSource.getConnection();
 System.out.println(conn);
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
18天前
|
XML 安全 Java
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
2天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
28 3
|
1月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
16天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
27 1
|
2月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
80 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
134 1
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
223 2
|
3天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
39 14
下一篇
DataWorks