`
soongbo
  • 浏览: 88584 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用Java注解特性加载属性文件(properties)的值到Java类

阅读更多

在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开发中,经常需要读取配置文件中的信息,例如数据库连接信息、系统环境变量等。这些配置通常存储在`.properties`文件中,便于维护和管理。本文将详细...

    JAVA读取properties文件的值

    它允许将整个文件映射到一个Java类,简化了属性的使用: ```java @ConfigurationProperties(prefix = "database") public class DatabaseConfig { private String name; private String url; // getters and ...

    java实现properties文件读取

    `java.util.Properties`是Java提供的一个类,它继承了`Hashtable`,主要用于处理属性列表(键/值对)。以下是如何创建和加载Properties文件的基本步骤: 1. **创建Properties对象**: 在Java代码中,我们首先创建...

    加载properties配置文件的几种方法

    在Spring Boot应用中,可以使用`@ConfigurationProperties`注解将properties文件中的配置映射到一个Java类的字段上。首先,创建一个配置类: ```java @ConfigurationProperties(prefix = "database") public ...

    java读取.properties配置文件的几种方法

    在这个例子中,我们首先创建一个`Properties`对象,然后通过`FileInputStream`打开配置文件,使用`load()`方法加载属性,最后用`getProperty()`获取指定键的值。 2. 使用`ResourceBundle`类 `ResourceBundle`类...

    Spring3.0 配置文件中加载Properties文件的小例子

    加载Properties文件后,我们就可以在其他bean的配置中引用这些属性值。假设我们有一个数据源bean,其配置如下: ```xml class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt; ${db.driver...

    读取.properties文件

    `load()`方法将文件内容加载到`Properties`对象中,之后我们可以使用`getProperty()`方法获取特定的属性值。 此外,对于大型项目,可能需要更高级的解决方案,例如使用Spring框架的`@Value`注解或`@...

    动态加载属性文件与SpringQuartz的应用

    具体实现上,可以创建一个专门的配置加载器类,负责监听属性文件的变化并更新到内存中的配置。同时,Spring Quartz的作业和触发器配置可以引用这些动态加载的属性。例如,使用`@Value`注解从属性文件中注入触发器的...

    如何读取webroot文件下的属性文件

    在Spring框架中,可以使用`Resource`接口和`ApplicationContext`来加载属性文件,这在多环境配置或类路径资源加载时非常有用: ```java Resource resource = new ClassPathResource("config.properties"); ...

    用enum实现单例模式的方法来读取配置文件

    本篇将详细介绍如何利用枚举(enum)来实现单例模式,并结合`Properties`类解析配置文件。 首先,我们来看一下传统的单例模式实现方式,如懒汉式和饿汉式,但这些方法在多线程环境下可能会存在问题。而使用枚举实现...

    JAVA Spring使用外部属性文件

    本文将深入探讨如何在Spring应用中利用外部属性文件,以及其背后的原理和优势。 首先,Spring框架支持多种类型的属性文件,包括`.properties`和`.yaml`格式。`.properties`文件是传统的键值对格式,而`.yaml`(YAML...

    Spring动态加载配置文件

    `PropertyPlaceholderConfigurer`是Spring早期版本中处理属性文件的工具,而`@PropertySource`则是从Spring 3.1引入的新特性,它们都可以用来从外部属性文件中读取值并注入到bean中。 1. `...

    SSM 读取properties文件

    这是一个Spring的bean定义类,它允许我们从properties文件中加载和解析属性值,然后将这些值注入到其他bean的属性中。首先,我们需要创建一个properties文件,例如`application.properties`,并放入项目的类路径下...

    java读取配置文件源代码

    这里,我们关注的是如何使用Java来读取配置文件,这通常涉及到`java.util.Properties`类和文件I/O操作。 标题“java读取配置文件源代码”表明我们将讨论一个Java程序,该程序用于从`.properties`文件中加载和解析...

    ReadProperties读取java项目配置文件

    标题中的"ReadProperties读取java项目配置文件"意味着我们将讨论如何使用Java的Properties类来加载并解析`.properties`文件,以便在运行时获取这些配置信息。这通常是通过以下步骤完成的: 1. **创建Properties对象...

    让spring加载自己的properties配置文件,在代码中获得配置信息

    2. **@PropertySource注解**:如果你需要在特定的Java配置类中加载特定的配置文件,可以使用`@PropertySource`注解。例如: ```java @Configuration @PropertySource("classpath:socket-config.properties") ...

    SpringValue注解

    在上面的配置中,我们定义了一个名为 appProperty 的 Bean,该 Bean 使用 PropertyPlaceholderConfigurer 类来加载名为 config.properties 的 properties 文件。 使用 @Value 注解 在 Bean 中,可以使用 @Value ...

    properties动态获取参数

    6. **使用资源绑定**:在现代Java应用中,尤其是Spring框架中,可以直接通过`@Value`注解和`Environment`接口来动态获取`properties`文件中的值,这使得代码更简洁,更具可读性。 综上所述,"properties动态获取...

    properties文件修改

    6. **资源绑定**:在Spring框架中,可以使用`@Value`注解将`.properties`文件中的属性值注入到Java bean的字段或方法中,实现配置的动态绑定。 7. **国际化(i18n)**:`.properties`文件也常用于实现应用的多语言...

    java中配置文件数据库连接写法

    Java中配置文件数据库连接主要涉及以下几个步骤:创建.properties配置文件,使用Properties类读取配置,使用JDBC或连接池建立数据库连接,如果使用Spring框架,还可以利用其强大的依赖注入和自动配置功能。...

Global site tag (gtag.js) - Google Analytics