在Spring中JavaBean的初始化顺序就是为现在写这个做准备的,要实现现在说的这个功能,大体方案有如下:
1.定义一个注解类
2.在需要加载属性的JavaBean的属性set方法上写注解,注解的参数就是key
3.在Spring启动的时候,去读取属性文件,然后把值赋给JavaBean
我们在上一篇写在Spring中JavaBean的初始化顺序提到了,如果一个JavaBean实现了BeanPostProcessor接口,那么其他Bean初始化以后都会交给这个Bean来处理.这样我们就可以写一个JavaBean实现BeanPostProcessor接口,这个Bean有个属性,它指向属性文件路径,在这个Bean初始化的时候读取属性文件内容,然后在postProcessBeforeInitialization方法里面对写了注解的Bean进行赋值.这样一个实现思路似乎很顺其自然,都是自己觉得不是很好,Spring通过PropertyPlaceholderConfigurer这样类来加载属性文件,而我们有写了另外一个类,这样一是不够统一,二是不够可能会造成多个属性文件.解决办法就是扩展PropertyPlaceholderConfigurer类.写一个类继承PropertyPlaceholderConfigurer类.然后在PropertyPlaceholderConfigurer初始化完成以后,获取加载的属性文件内容,在postProcessBeforeInitialization里面把写过注解的类属性进行赋值.那么怎么确定什么时候PropertyPlaceholderConfigurer加载完成呢,根据Spring中JavaBean的初始化顺序,我们知道一个JavaBean如果实现了InitializingBean接口,那么Spring容器会在这个Bean初始化以后调用afterPropertiesSet方法,现在我写个类继承PropertyPlaceholderConfigurer类,实现BeanPostProcessor, InitializingBean 这个两个接口那么刚刚提到的问题就可以解决了,下面是实现代码
package com.test.annotation;
import java.lang.reflect.Method;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.util.ReflectionUtils;
public class AnnotationBeanPostProcessor extends PropertyPlaceholderConfigurer implements BeanPostProcessor, InitializingBean {
private java.util.Properties pros;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// TODO Auto-generated method stub
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if(bean.getClass().getAnnotation(Property.class)!=null){
Method[] methods = bean.getClass().getDeclaredMethods();
for (Method method : methods) {
Property p = method.getAnnotation(Property.class);
if(p!=null){
// 这里进行参数类型转换
Object para=pros.getProperty(p.name());
if((method.getParameterTypes()[0]).getName().equals("java.lang.Integer")){
para= new Integer(para.toString());
}
ReflectionUtils.invokeMethod(method, bean, new Object[]{para});
}
}
}
return bean;
}
@Override
public void afterPropertiesSet() throws Exception {
pros = mergeProperties();
}
}
package com.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Property {
String name() default "";
}
package com.test;
import com.test.annotation.Property;
@Property
public class Bean {
private String name;
private Integer age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
@Property(name="com.test.Bean.address")
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
@Property(name="com.test.Bean.age")
public void setAge(Integer age) {
this.age = age;
}
}
package com.test;
import com.test.annotation.Property;
@Property
public class JavaBean {
private String name;
private String address;
public String getName() {
return name;
}
@Property(name="com.test.JavaBean.name")
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
System.out.println("加载配置文件结束");
System.out.println("--------------------------------------------");
JavaBean javaBean=(JavaBean)context.getBean("javaBean");
System.out.println(javaBean.getName());
System.out.println(javaBean.getAddress());
System.out.println("--------------------------------------------");
Bean bean=(Bean)context.getBean("bean");
System.out.println(bean.getName());
System.out.println(bean.getAddress());
System.out.println(bean.getAge());
System.out.println("--------------------------------------------");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id=
attribute-value>"propertyConfigurer" class="com.test.annotation.AnnotationBeanPostProcessor">
<property name="locations">
<list>
<value>classpath*:system.properties</value>
</list>
</property>
</bean>
<bean id="javaBean" class="com.test.JavaBean">
<property name="address" value="${com.test.JavaBean.address}"></property>
</bean>
<bean id="bean" class="com.test.Bean">
<property name="name" value="${com.test.Bean.name}"></property>
</bean>
</beans>
ps:之所以要继承PropertyPlaceholderConfigurer类,还有一个原因就是,原来通过${}注入值的方式还可以用
BeanPostProcessor有两个方法,为什么要写在postProcessBeforeInitialization里面,而不是postProcessAfterInitialization里面,原因在于postProcessBeforeInitialization方法是在Bean的init方法之前执行,在init方法里面可能会用到类的属性,所以必须在init方法执行之前先赋值好.
<!-- 分页 -->
分享到:
相关推荐
### Java 类文件通过 $ 获取 properties 文件的属性值 在Java开发中,经常需要读取配置文件中的信息,例如数据库连接信息、系统环境变量等。这些配置通常存储在`.properties`文件中,便于维护和管理。本文将详细...
它允许将整个文件映射到一个Java类,简化了属性的使用: ```java @ConfigurationProperties(prefix = "database") public class DatabaseConfig { private String name; private String url; // getters and ...
`java.util.Properties`是Java提供的一个类,它继承了`Hashtable`,主要用于处理属性列表(键/值对)。以下是如何创建和加载Properties文件的基本步骤: 1. **创建Properties对象**: 在Java代码中,我们首先创建...
在Spring Boot应用中,可以使用`@ConfigurationProperties`注解将properties文件中的配置映射到一个Java类的字段上。首先,创建一个配置类: ```java @ConfigurationProperties(prefix = "database") public ...
在这个例子中,我们首先创建一个`Properties`对象,然后通过`FileInputStream`打开配置文件,使用`load()`方法加载属性,最后用`getProperty()`获取指定键的值。 2. 使用`ResourceBundle`类 `ResourceBundle`类...
加载Properties文件后,我们就可以在其他bean的配置中引用这些属性值。假设我们有一个数据源bean,其配置如下: ```xml class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> ${db.driver...
`load()`方法将文件内容加载到`Properties`对象中,之后我们可以使用`getProperty()`方法获取特定的属性值。 此外,对于大型项目,可能需要更高级的解决方案,例如使用Spring框架的`@Value`注解或`@...
具体实现上,可以创建一个专门的配置加载器类,负责监听属性文件的变化并更新到内存中的配置。同时,Spring Quartz的作业和触发器配置可以引用这些动态加载的属性。例如,使用`@Value`注解从属性文件中注入触发器的...
在Spring框架中,可以使用`Resource`接口和`ApplicationContext`来加载属性文件,这在多环境配置或类路径资源加载时非常有用: ```java Resource resource = new ClassPathResource("config.properties"); ...
本篇将详细介绍如何利用枚举(enum)来实现单例模式,并结合`Properties`类解析配置文件。 首先,我们来看一下传统的单例模式实现方式,如懒汉式和饿汉式,但这些方法在多线程环境下可能会存在问题。而使用枚举实现...
本文将深入探讨如何在Spring应用中利用外部属性文件,以及其背后的原理和优势。 首先,Spring框架支持多种类型的属性文件,包括`.properties`和`.yaml`格式。`.properties`文件是传统的键值对格式,而`.yaml`(YAML...
`PropertyPlaceholderConfigurer`是Spring早期版本中处理属性文件的工具,而`@PropertySource`则是从Spring 3.1引入的新特性,它们都可以用来从外部属性文件中读取值并注入到bean中。 1. `...
这是一个Spring的bean定义类,它允许我们从properties文件中加载和解析属性值,然后将这些值注入到其他bean的属性中。首先,我们需要创建一个properties文件,例如`application.properties`,并放入项目的类路径下...
这里,我们关注的是如何使用Java来读取配置文件,这通常涉及到`java.util.Properties`类和文件I/O操作。 标题“java读取配置文件源代码”表明我们将讨论一个Java程序,该程序用于从`.properties`文件中加载和解析...
标题中的"ReadProperties读取java项目配置文件"意味着我们将讨论如何使用Java的Properties类来加载并解析`.properties`文件,以便在运行时获取这些配置信息。这通常是通过以下步骤完成的: 1. **创建Properties对象...
2. **@PropertySource注解**:如果你需要在特定的Java配置类中加载特定的配置文件,可以使用`@PropertySource`注解。例如: ```java @Configuration @PropertySource("classpath:socket-config.properties") ...
在上面的配置中,我们定义了一个名为 appProperty 的 Bean,该 Bean 使用 PropertyPlaceholderConfigurer 类来加载名为 config.properties 的 properties 文件。 使用 @Value 注解 在 Bean 中,可以使用 @Value ...
6. **使用资源绑定**:在现代Java应用中,尤其是Spring框架中,可以直接通过`@Value`注解和`Environment`接口来动态获取`properties`文件中的值,这使得代码更简洁,更具可读性。 综上所述,"properties动态获取...
6. **资源绑定**:在Spring框架中,可以使用`@Value`注解将`.properties`文件中的属性值注入到Java bean的字段或方法中,实现配置的动态绑定。 7. **国际化(i18n)**:`.properties`文件也常用于实现应用的多语言...
Java中配置文件数据库连接主要涉及以下几个步骤:创建.properties配置文件,使用Properties类读取配置,使用JDBC或连接池建立数据库连接,如果使用Spring框架,还可以利用其强大的依赖注入和自动配置功能。...