Spring-引用Bean的属性值

简介: Spring-引用Bean的属性值

概述


将应用系统的配置信息存放在配置文件中并非总是最合适的,如果应用以集群的方式部署,或者希望在运行期动态调整引用的某些配置,这时,将配置信息放到数据库中不但方便集中管理,而且可以通过应用系统的管理界面动态维护,有效增强应用系统的可维护性。


早期版本,如果想在配置文件中引用另外一个Bean的属性值是比较麻烦的,Spring3.0则提供了优雅的解决方案. 在Spring3.0中,可以通过类似 #{beanName.beanPro}的方式方便的引用另外一个Bean的值。


实例


代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

假设数据库中有张TEMP_SYS_CONFIG表,数据如下

20170808044112802.jpg


基于XML方式的引用



20170808050956310.jpg

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"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入  扫描@Autowired -->
    <context:component-scan base-package="com.xgj.ioc.refOtherBeanProByXml"/>
    <!-- 定义Bean,通过initFromDB初始化方法从数据库中加载数据 -->
    <bean id="sysConfig" class="com.xgj.ioc.refOtherBeanProByXml.SysConfig"
         init-method="initFromDB"/>
    <!-- 引用sysConfig Bean的属性值 -->
    <bean id="applicationManager" class="com.xgj.ioc.refOtherBeanProByXml.ApplicationManager"
        p:sessionTimeout="#{sysConfig.sessionTimeout}"
        p:maxTabPageNum="#{sysConfig.maxTabPageNum}"/>
    <!-- 使用context命名空间 引入外部属性文件 -->
     <context:property-placeholder location="classpath:spring/jdbc.properties" />
    <!-- 通过属性名引用属性值 -->     
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.url}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}"/>
    <!-- 配置Jdbc模板  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
        p:dataSource-ref="dataSource" />
</beans>


SysConfig.java

package com.xgj.ioc.refOtherBeanProByXml;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
public class SysConfig {
    public int sessionTimeout;
    public int maxTabPageNum;
    private JdbcTemplate jdbcTemplate;
    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    /**
     * 
     * 
     * @Title: initFromDB
     * 
     * @Description: 从数据库中初始化sessionTimeout和maxTabPageNum属性
     * 
     * 
     * @return: void
     */
    public void initFromDB() {
        System.out.println("initFrom DB");
        final List<String> paramList = new ArrayList<String>();
        String sql = " select  value  from TEMP_SYS_CONFIG a where a.code in ('sessionTimeout' ,'maxTabPageNum') ";
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                paramList.add(rs.getString("value"));
            }
        });
        sessionTimeout = Integer.parseInt(paramList.get(0));
        maxTabPageNum = Integer.parseInt(paramList.get(1));
    }
}


ApplicationManager.java

package com.xgj.ioc.refOtherBeanProByXml;
public class ApplicationManager {
    private int sessionTimeout;
    private int maxTabPageNum;
    public int getSessionTimeout() {
        System.out.println("sessionTimeout:" + sessionTimeout);
        return sessionTimeout;
    }
    public void setSessionTimeout(int sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }
    public int getMaxTabPageNum() {
        System.out.println("maxTabPageNum:" + maxTabPageNum);
        return maxTabPageNum;
    }
    public void setMaxTabPageNum(int maxTabPageNum) {
        this.maxTabPageNum = maxTabPageNum;
    }
}


测试类

package com.xgj.ioc.refOtherBeanProByXml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanPropReferenceTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/ioc/refOtherBeanProByXml/beans.xml");
        ApplicationManager applicationManager = ctx.getBean(
                "applicationManager", ApplicationManager.class);
        applicationManager.getSessionTimeout();
        applicationManager.getMaxTabPageNum();
    }
}


运行结果:

20170808051745773.jpg


基于注解的引用


在基于注解和基于JAVA类配置的Bean中,可以通过@Value(“#{beanName.beanPro}”)的注解形式引用Bean的属性值

20170808044257546.jpg

通过在配置文件中配置context:component-scan ,扫描标注了注解的POJO,实例化并缓存。

配置文件:

<?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"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
    <context:component-scan base-package="com.xgj.ioc.refOtherBeanPro"/>
    <!-- 使用context命名空间 引入外部属性文件 -->
     <context:property-placeholder location="classpath:spring/jdbc.properties" />
    <!-- 通过属性名引用属性值 -->     
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.url}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}"/>
    <!-- 配置Jdbc模板  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
        p:dataSource-ref="dataSource" />
</beans>


SysConfig.java

package com.xgj.ioc.refOtherBeanPro;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Component;
@Component
public class SysConfig {
    public int sessionTimeout;
    public int maxTabPageNum;
    private JdbcTemplate jdbcTemplate;
    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    /**
     * 
     * 
     * @Title: initFromDB
     * 
     * @Description: 从数据库中初始化sessionTimeout和maxTabPageNum属性
     * 
     * 
     * @return: void
     */
    @PostConstruct
    public void initFromDB() {
        System.out.println("initFrom DB");
        final List<String> paramList = new ArrayList<String>();
        String sql = " select  value  from TEMP_SYS_CONFIG a where a.code in ('sessionTimeout' ,'maxTabPageNum') ";
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                paramList.add(rs.getString("value"));
            }
        });
        sessionTimeout = Integer.parseInt(paramList.get(0));
        maxTabPageNum = Integer.parseInt(paramList.get(1));
    }
}


ApplicationManager.java

package com.xgj.ioc.refOtherBeanPro;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ApplicationManager {
    private int sessionTimeout;
    private int maxTabPageNum;
    public int getSessionTimeout() {
        System.out.println("sessionTimeout:" + sessionTimeout);
        return sessionTimeout;
    }
    @Value("#{sysConfig.sessionTimeout}")
    public void setSessionTimeout(int sessionTimeout) {
        this.sessionTimeout = sessionTimeout;
    }
    public int getMaxTabPageNum() {
        System.out.println("maxTabPageNum:" + maxTabPageNum);
        return maxTabPageNum;
    }
    @Value("#{sysConfig.maxTabPageNum}")
    public void setMaxTabPageNum(int maxTabPageNum) {
        this.maxTabPageNum = maxTabPageNum;
    }
}


测试类

package com.xgj.ioc.refOtherBeanPro;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanPropReferenceTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/ioc/refOtherBeanPro/beans.xml");
        ApplicationManager applicationManager = ctx.getBean(
                "applicationManager", ApplicationManager.class);
        applicationManager.getSessionTimeout();
        applicationManager.getMaxTabPageNum();
    }
}


运行结果:

20170808044632689.jpg


相关文章
|
29天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
14天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
67 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
81 1
|
1月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
40 1
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
85 1
|
2月前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
166 2