Spring5参考指南:容器扩展

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Spring5参考指南:容器扩展

文章目录



Spring提供了一系列的接口来提供对Spring容器的扩展功能。下面我们一一介绍。


BeanPostProcessor自定义bean


前面一篇文章我们在自定义bean中提到,可以实现Spring的InitializingBean和DisposableBean接口来实现自定义bean的生命周期。如果是容器级别的,Spring提供了更加强大的BeanPostProcessor,来实现在容器级对Bean的扩展。


BeanPostProcessor接口定义了两个方法:


default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }


该方法在调用容器初始化方法(如InitializingBean.afterPropertiesSet()或任何声明的init方法)之前,以及在任何bean初始化之后,被调用。


default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }


该方法在容器初始化方法之后被调用。


BeanPostProcessor可以配置多个,如果想控制多个BeanPostProcessor的顺序,可以实现Ordered接口,来定义他们的顺序。


虽然BeanPostProcessor是通过ApplicationContext自动检测的,你也可通过ConfigurableBeanFactory的addBeanPostProcessor来手动注册。手动注册则其Ordered失效,以手动注册的先后为准。


还要注意,以编程方式注册的BeanPostProcessor实例总是在注册为自动检测的实例之前进行处理,而不接收任何显式排序。


所有BeanPostProcessor实例和这些实例直接引用的bean都在启动时实例化,因为AOP自动代理是作为BeanPostProcessor本身实现的,所以BeanPostProcessor实例和它们直接引用的bean都不符合自动代理的条件。


下面是一个调用的例子:


<bean id="beanA" class="com.flydean.beans.BeanA"/>
    <bean id="beanB" class="com.flydean.beans.BeanB"/>
    <bean class="com.flydean.beans.InstantiationTracingBeanPostProcessor"/>


调用实现:


public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-post-processor.xml");
        BeanA beanA = (BeanA) ctx.getBean("beanA");
        System.out.println(beanA);
    }


BeanFactoryPostProcessor自定义配置元数据


BeanFactoryPostProcessor接口的语义与BeanPostProcessor的语义相似,但有一个主要区别:BeanFactoryPostProcessor对Bean配置元数据进行操作。也就是说,Spring IOC容器允许BeanFactoryPostProcessor读取配置元数据,并可能在容器实例化BeanFactoryPostProcessor实例以外的任何bean之前对其进行更改。


BeanFactoryPostProcessor也可以配置多个,并通过实现Ordered接口来确定执行顺序。BeanFactoryPostProcessor定义了一个方法:


void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;


通过该方法可以获取到可配置的beanFactory从而对bean定义进行修改。


Spring提供了很多预定义的bean工厂后处理器,例如PropertyOverrideConfigurer和PropertyPlaceholderConfigurer。下面我们通过例子来说明怎么使用。


PropertyOverrideConfigurer类名替换


PropertyPlaceholderConfigurer主要用于从外部的Property文件读取属性,用来替换定义好的配置,这样做可以使部署应用程序的人员自定义特定于环境的属性,如数据库URL和密码,而不必为容器修改一个或多个XML定义主文件从而增加复杂性或风险。


下面是配置的XML文件:


<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:jdbc.properties"/>
    </bean>
    <bean id="dataSource" destroy-method="close"
          class="com.flydean.beans.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>


这个例子展示了属性被配置在外部的Properties文件中。在运行时,使用PropertyPlaceholderConfigurer将元数据替换成DataSource中的某些属性。要替换的值被指定为${property-name}格式的占位符,该格式遵循ant和log4j以及JSP EL样式。


真实的值取自外部的Java Properties格式的文件:


jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root


PropertyOverrideConfigurer属性覆盖


PropertyOverrideConfigurer可以用来覆盖Bean属性的默认值,或者设置新的值。我们看一个例子:


<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
        <property name="locations" value="classpath:override.properties"/>
        <property name="properties">
            <value>beanOverride.url=com.something.DefaultStrategy</value>
        </property>
    </bean>
    <bean name="beanOverride" class="com.flydean.beans.BeanOverride"/>


对应的类是:


@Data
public class BeanOverride {
    private String name="beanA";
    private String url="http://www.163.com";
}


它的默认属性会被覆盖。


使用FactoryBean自定义实例化逻辑


FactoryBean接口提供3个方法:


  • Object getObject(): 返回工厂创建的实例,该实例可能是被共享的, 取决于该实例是单例还是多例模式。
  • boolean isSingleton():判断FactoryBean返回的是单例还是多例。
  • Class getObjectType():返回getObject() 方法返回的类型,如果提前不知道类型,那么返回null。


我们可以实现FactoryBean接口来自定义Bean的实现逻辑。


public class BeanFactoryBean implements FactoryBean {
    @Resource
    private BeanA beanA;
    @Override
    public Object getObject() throws Exception {
        return beanA;
    }
    @Override
    public Class<?> getObjectType() {
        return BeanA.class;
    }
}


下面是其配置:


<context:annotation-config/>
    <bean id="beanA" class="com.flydean.beans.BeanA"/>
    <bean id="beanFactoryBean" class="com.flydean.beans.BeanFactoryBean"/>


如何使用?


public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factory.xml");
        BeanFactoryBean beanFactoryBean = (BeanFactoryBean) ctx.getBean("&beanFactoryBean");
        System.out.println(beanFactoryBean.getObject());
        System.out.println(beanFactoryBean.getObjectType());
        BeanA beanA=(BeanA)ctx.getBean("beanFactoryBean");
        System.out.println(beanA);
    }


当需要向容器请求实际的FactoryBean实例本身而不是它生成的bean时,在调用ApplicationContext的getbean()方法时,在bean的ID前面加上符号(&)。


因此,对于ID为beanFactoryBean的给定FactoryBean,在容器上调用getBean(“beanFactoryBean”)返回FactoryBean生成的bean,


而调用getBean(“&beanFactoryBean”)则返回FactoryBean实例本身。

相关文章
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
2月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
120 3
|
2月前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
204 3
|
3月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
3月前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
8天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
35 2
|
18天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
14天前
|
关系型数据库 MySQL API