spring bean 初始化问题

问题描述

我有2个bean:A,BA里有字段用@Value注入,A还有个初始化方法;B里的初始化方法需要用到A的@Value字段和初始化方法的结果请问我该怎么配置才能让B正确初始化? 问题补充:只用@Resource和@PostConstruct的话,其实没什么问题的,关键是用到了@Value,@Value注入的时间似乎比@PostConstruct更迟@Servicepublic class SQLPropertiesLoader { @Value("#{sqlProperties['REPORT.UPDATE']}") private String reportUpdateSQL; public String getReportUpdateSQL(){ return reportUpdateSQL; }//等等}@Servicepublic class Job{@Resourceprivate SQLPropertiesLoader sqlProperties; @PostConstruct public init(){ String sql = sqlProperties.getReportUpdateSQL(); //等等 } @Async @Scheduled(fixedDelay = 10000L) public void job() //等等 }

解决方案

@Value注入的时间比@PostConstruct更早,我修改了一下范例。A.javaimport org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.ImportResource;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.Resource;@Component("a")@ImportResource("classpath:./properties-config.xml")public class A {@Resource(name = "aInject")private AInject aInject;@Value("#{testp[a_one]}")private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public AInject getaInject() {return aInject;}public void setaInject(AInject aInject) {this.aInject = aInject;}@PostConstructpublic void initA() {System.out.printf("A init do. [%s]n", this.getMessage());}}properties-config.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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd" default-autowire="byName" default-lazy-init="true"><util:properties id="testp" location="classpath:./test.properties"/></beans>ABTest.javaimport org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import scan.A;import scan.B;public class ABTest {private ApplicationContext ctx;private A a;private B b;@Beforepublic void init() {ctx = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/applicationContext-bean.xml"});b = ctx.getBean("b", B.class);a = ctx.getBean("a", A.class);}@Testpublic void testAB() {System.out.printf("Msg:%s@%s@%sn", a.getaInject().getInjectName(), b.getA().getaInject().getInjectName(),a.getMessage());a.getaInject().sayHello();}}test.propertiesa_one=Hello执行ABTest测试的结果:A init do. [Hello]B init do.Msg:A inject.@A inject.@HelloHello A inject.!注意看在@PostConstruct的方法中@Value已经注入成功!
解决方案二:
我假设你使用的Spring是2.5+版本,下面的例子对你应该有帮助:applicationContext-bean.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-autowire="byName" default-lazy-init="true"> <context:component-scan base-package="scan" /></beans>A.javapackage scan;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.Resource;@Component("a")public class A {@Resource(name = "aInject")private AInject aInject;public AInject getaInject() {return aInject;}public void setaInject(AInject aInject) {this.aInject = aInject;}@PostConstructpublic void initA() {System.out.println("A init do.");}}B.javapackage scan;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.Resource;/** * User: phoenixup * Date: 11-3-15 * Time: 下午12:29 * Desc: //TODO:WRITE YOUR OWN DESCRIPTION. */@Component("b")public class B {@Resource(name = "a")private A a;public A getA() {return a;}public void setA(A a) {this.a = a;}@PostConstructpublic void initB() {System.out.println("B init do.");}}AInject.javapackage scan;import org.springframework.stereotype.Service;@Service("aInject")public class AInject {private String injectName = "A inject.";public String getInjectName() {return injectName;}public void setInjectName(String injectName) {this.injectName = injectName;}/*other thing*/public void sayHello() {System.out.printf("Hello %s!n", injectName);}}ABTest.javaimport org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import scan.A;import scan.B;public class ABTest {private ApplicationContext ctx;private A a;private B b;@Beforepublic void init() {ctx = new ClassPathXmlApplicationContext(new String[]{"/applicationContext-bean.xml"});b = ctx.getBean("b", B.class);a = ctx.getBean("a", A.class);}@Testpublic void testAB() {System.out.printf("Msg:%s@%sn", a.getaInject().getInjectName(), b.getA().getaInject().getInjectName());a.getaInject().sayHello();}}测试包使用的junit,运行ABtest测试,可以得到的结果:A init do.B init do.Msg:A inject.@A inject.Hello A inject.!注意消息的次序,应该可以满足你的要求。关于@Resource、@PostConstruct注解的方法可以查阅文档。如果你使用的spring版本不支持注解,修改applicationContext-bean.xml,在<bean/>元素中使用init-method属性也可以满足要求。

时间: 2024-07-30 22:05:29

spring bean 初始化问题的相关文章

当spring 容器初始化完成后执行某个方法

在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出哪个文件的xml文件使用了这个函数. 而在Spring的web项目中,我们可以介入Spring的启动过程.我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,这个时候我们就可以实现一个接口: 1 2 3 4 5 6 7 package com.yk.test.executor.p

Spring Bean的作用域(转)

  Spring Bean的作用域 .singleton  [单例] eg:<bean id="personService" class="com.yinger.service.impl.PersonServiceBean" scope="singleton"></bean> 在每个Spring IoC容器中一个bean定义只有一个对象实例. 请注意Spring的singleton bean概念与"四人帮&quo

spring bean加载--从缓存中获取bean

标签:spring源码学习 入口方法:getSingleton,在 Object sharedInstance = getSingleton(beanName); @Override public Object getSingleton(String beanName) { return getSingleton(beanName, true); } 真正的实现: protected Object getSingleton(String beanName, boolean allowEarlyR

Spring Bean的生命周期管理

本文来自阅读Life Cycle Management of a Spring Bean这篇文章所做的笔记和实验. 按图索骥 bean的生命周期 知识点 1. BeanNameAware接口 Spring Bean存活于容器之中,一般情况下spring bean对context的情况并不了解,如果希望某个bean知道自己在context中的代号:bean name,即可让该bean的类型实现BeanNameAware接口. package org.test.spittr.spi; import

Spring Bean延迟实例化是什么意思

问题描述 最近回顾知识,看到Spring Bean延迟实例化这个概念,发现有点不甚理解,还请高手们指教一番,谢谢! 解决方案 如果看控制台输出,你会发现在启动时候spring输出很多信息,其中就有初始化BEAN.延迟初始化就是不在这时候初始化.在你第一次使用的时候才创建然后交给spring管理.解决方案二:ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化.提前实例化意味着作为初始化过程的一部分,ApplicationContext实例

请问servlet如何获取通过annotation方式配置的spring bean?

问题描述 如题,通过xml配置文件管理的spring bean可以在普通的servlet中用ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext等方式获取使用,但通过annotation方式管理的spring bean如果需要在servlet中使用,该用什么方式呢?谢谢 问题补充:我想知道的是用什么哪一种ApplicationContext去获取,难道还是ClassPathXmlApplicationContext吗? 解

Spring Bean的生命周期详细介绍_java

Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring容器.这里,我们讲的也是 ApplicationContext中Bean的生命周期.而实际上BeanFactory也是差不多的,只不过处理器需要手动注册. 一.生命周期流程图: Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关

javaweb项目,tomcat启动异常报错,spring文件初始化问题,大神help

问题描述 javaweb项目,tomcat启动异常报错,spring文件初始化问题,大神help 本地启动没问题,把编译好的项目放到别的机器就不行,tomcat版本是一样的,都是8.0.12,jdk也是一样的,本地的系统是windows,另外一台是linux ERROR 2015-08-13 14:50:01,873 ContextLoader:initWebApplicationContext - Context initialization failed java.lang.NullPoin

spring bean 属性从配置文件读取

问题描述 spring bean 属性从配置文件读取 我在spring的xml文件中使用这个标签: <context:component-scan base-package="${serverPack}"/> 启动${serverPack}从配置文件中获取,现在启动Tomcat出错. 解决方案 Spring bean配置读取配置文件Spring中读取bean配置文件的几种方式用dom4j读取配置文件来模拟spring的bean工厂 解决方案二: 要读取.properties