`
zhjb2000
  • 浏览: 58303 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

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

阅读更多

在此之前我都是写个PropertyUtil类来加载配置文件,然后通过get方法,把key对应的值取出来.

Spring提供一个PropertyPlaceholderConfigurer类,可以读取配置文件,然后在Spring配置文件通过${hibernate.dialect}这种方式注入到JavaBean中,有个不好的地方就是,要在代码中取的时候不是很方便.

然后在接触到Java注解特注解技术以后,感觉这个东东很好,hibernate映射,WebService都可以通过注解来完成,方便的很多,然后就在想能不能通过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 这个两个接口那么刚刚提到的问题就可以解决了,下面是实现代码

  1. packagecom.test.annotation;
  2. importjava.lang.reflect.Method;
  3. importorg.springframework.beans.BeansException;
  4. importorg.springframework.beans.factory.InitializingBean;
  5. importorg.springframework.beans.factory.config.BeanPostProcessor;
  6. importorg.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
  7. importorg.springframework.util.ReflectionUtils;
  8. publicclassAnnotationBeanPostProcessorextendsPropertyPlaceholderConfigurerimplementsBeanPostProcessor,InitializingBean{
  9. privatejava.util.Propertiespros;
  10. @Override
  11. publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)
  12. throwsBeansException{
  13. //TODOAuto-generatedmethodstub
  14. returnbean;
  15. }
  16. @Override
  17. publicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)
  18. throwsBeansException{
  19. if(bean.getClass().getAnnotation(Property.class)!=null){
  20. Method[]methods=bean.getClass().getDeclaredMethods();
  21. for(Methodmethod:methods){
  22. Propertyp=method.getAnnotation(Property.class);
  23. if(p!=null){
  24. //这里进行参数类型转换
  25. Objectpara=pros.getProperty(p.name());
  26. if((method.getParameterTypes()[0]).getName().equals("java.lang.Integer")){
  27. para=newInteger(para.toString());
  28. }
  29. ReflectionUtils.invokeMethod(method,bean,newObject[]{para});
  30. }
  31. }
  32. }
  33. returnbean;
  34. }
  35. @Override
  36. publicvoidafterPropertiesSet()throwsException{
  37. pros=mergeProperties();
  38. }
  39. }
  1. packagecom.test.annotation;
  2. importjava.lang.annotation.Retention;
  3. importjava.lang.annotation.RetentionPolicy;
  4. importjava.lang.annotation.Target;
  5. importjava.lang.annotation.ElementType;
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Target({ElementType.TYPE,ElementType.METHOD})
  8. public@interfaceProperty{
  9. Stringname()default"";
  10. }
  1. packagecom.test;
  2. importcom.test.annotation.Property;
  3. @Property
  4. publicclassBean{
  5. privateStringname;
  6. privateIntegerage;
  7. privateStringaddress;
  8. publicStringgetName(){
  9. returnname;
  10. }
  11. publicvoidsetName(Stringname){
  12. this.name=name;
  13. }
  14. publicStringgetAddress(){
  15. returnaddress;
  16. }
  17. @Property(name="com.test.Bean.address")
  18. publicvoidsetAddress(Stringaddress){
  19. this.address=address;
  20. }
  21. publicIntegergetAge(){
  22. returnage;
  23. }
  24. @Property(name="com.test.Bean.age")
  25. publicvoidsetAge(Integerage){
  26. this.age=age;
  27. }
  28. }
  1. packagecom.test;
  2. importcom.test.annotation.Property;
  3. @Property
  4. publicclassJavaBean{
  5. privateStringname;
  6. privateStringaddress;
  7. publicStringgetName(){
  8. returnname;
  9. }
  10. @Property(name="com.test.JavaBean.name")
  11. publicvoidsetName(Stringname){
  12. this.name=name;
  13. }
  14. publicStringgetAddress(){
  15. returnaddress;
  16. }
  17. publicvoidsetAddress(Stringaddress){
  18. this.address=address;
  19. }
  20. }
  1. packagecom.test;
  2. importorg.springframework.context.ApplicationContext;
  3. importorg.springframework.context.support.ClassPathXmlApplicationContext;
  4. publicclassTest{
  5. /**
  6. *@paramargs
  7. */
  8. publicstaticvoidmain(String[]args){
  9. ApplicationContextcontext=
  10. newClassPathXmlApplicationContext("spring.xml");
  11. System.out.println("加载配置文件结束");
  12. System.out.println("--------------------------------------------");
  13. JavaBeanjavaBean=(JavaBean)context.getBean("javaBean");
  14. System.out.println(javaBean.getName());
  15. System.out.println(javaBean.getAddress());
  16. System.out.println("--------------------------------------------");
  17. Beanbean=(Bean)context.getBean("bean");
  18. System.out.println(bean.getName());
  19. System.out.println(bean.getAddress());
  20. System.out.println(bean.getAge());
  21. System.out.println("--------------------------------------------");
  22. }
  23. }
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
  3. <beans>
  4. <beanid="propertyConfigurer"class="com.test.annotation.AnnotationBeanPostProcessor">
  5. <propertyname="locations">
  6. <list>
  7. <value>classpath*:system.properties</value>
  8. </list>
  9. </property>
  10. </bean>
  11. <beanid="javaBean"class="com.test.JavaBean">
  12. <propertyname="address"value="${com.test.JavaBean.address}"></property>
  13. </bean>
  14. <beanid="bean"class="com.test.Bean">
  15. <propertyname="name"value="${com.test.Bean.name}"></property>
  16. </bean>
  17. </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