使用注解属性绑定

大家应该知道在Spring中有一个注解@Value,他可以帮助我们来讲Spring加载的配置文件(*.perperties)文件中的信息自动的注入到我们的非静态属性中的。

一般情况下我们会这样使用:

1.  首先在Spring的配置文件中加载属性文件:


1

<context:property-placeholder location="classpath:component.properties"  ignore-unresolvable="true"/>

然后在Java代码中使用@Value注解就可以注入值了,比如:

 


1

2

@Value("${open_office_install_home}")

private String openOfficeInstallHome;

 

当然属性如果是static的话是不能注入的。

 

其实这个自动注入的过程实现起来比较简单,我们下面通过一个例子来大致描述一下这个原理吧,这个例子是我写的,并不代表Spring的源码就是这么实现的。但是原理是一样的。

 

1.  我们先自定义一个注解:


1

2

3

4

5

6

7

8

9

10

11

12

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Value {

 

    public String value();

 

}

2. 然后新增一个处理类:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.util.Properties;

 

 

public class PropertyInvokationHandler implements InvocationHandler {

 

    private Properties properties;

 

    public PropertyInvokationHandler(Properties properties) {

        this.properties = properties;

    }

 

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Value annotation = method.getAnnotation(Value.class);

        if(annotation == null){

            throw new RuntimeException(String.format("Method:{} is not bound to a property.", method.getName()));

        }

        return properties.getProperty(annotation.value());

    }

}

3.  创建一个公共方法:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

import java.lang.reflect.Proxy;

import java.util.Properties;

 

public class PropertyTool {

 

    private PropertyTool() {

    }

 

    public static <T> T bindProperties(Class<T> clazz, Properties properties) {

        return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),

                new Class[]{clazz},

                new PropertyInvokationHandler(properties));

    }

}

这样我们就完成了这个功能了。

 

下面我们通过测试代码来验证一下我们的功能是否起作用:

我们创建一个接口:


1

2

3

4

5

6

7

8

9

public interface UserService {

 

    @Value("user.name")

    public String getUserName();

 

    @Value("user.password")

    public String getPassword();

 

}

然后编写测试类:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

 

public class UserServiceTester {

 

    public static void main(String[] args) {

        Properties properties = new Properties();

 

        try {

            String path = UserServiceTester.class.getResource("/user.properties").getPath();

            InputStream in = new FileInputStream(path);

            properties.load(in);

            in.close();

        catch(IOException ex) {

            ex.printStackTrace();

        }

 

        UserService config = PropertyTool.bindProperties(UserService.class, properties);

        System.out.println("User Name: " + config.getUserName());

        System.out.println("Password: " + config.getPassword());

    }

}

而我们的user.properties属性文件中的内容为:


1

2

user.name=rollenholt

user.password=123

运行上面的main方法,就会输出属性文件中的内容了。

 

不知道大家有没有注意到,我们在测试代码中使用的UserService是一个接口,我们并没有创建他的实现类,但是我们在main函数中依旧可以钓鱼他的方法。那是因为在运行时自动生成了一个实现。是不是觉的这个功能可以用在很多的地方呀。

 

时间: 2024-07-30 10:34:58

使用注解属性绑定的相关文章

QML静态值与属性绑定

简述 可以为 QML 对象中的属性分配两种类型的值 - 静态值和绑定表达式,后者也称为属性绑定. 静态值:一个不依赖于其他属性的常数值. 绑定表达式:一个用于描述属性间依赖关系的 JavaScript 表达式. 属性绑定是 QML 的一个核心特性,允许指定不同对象属性之间的依赖关系.当属性的依赖项(属性绑定中的变量)的值发生改变时,属性将根据指定的关系自动更新. 简述 静态值 属性绑定 使用属性绑定 从 JavaScript 创建属性绑定 在属性绑定中使用 this 版权所有:一去丶二三里,转载

Silverlight 5 beta新特性探索系列:7.结合上层元素属性绑定和Style Setter上的绑定

   在Silverlight 5中添加了相对上层元素属性的绑定,还有Style Setter也可以绑定数据.         一.相对上层元素属性的绑定        它是在元素内部的子孙级元素中的某一些属性可以绑定为祖先级元素的某一些属性.比如说再一个ListBox的Tag元素值为:"这是第一个父级绑定",在ListBox.Templete下面添加一个TextBlock元素的Text属性设置为 <TextBlock Text="{Binding Tag,Relati

JavaScript 事件属性绑定带参数的函数_javascript技巧

例如不能采用这种调用方式:element.onclick = test();element.onclick = test(arg1,arg2);只能通过element.onclick = function(){ ... };或者element.onclick = test这种方式来实现,所以无法给函数传递参数.参考了大量的网上资料,解决这个问题的方式,以代码为例,如下所示: 复制代码 代码如下: function Handler() { }; Handler.prototype = { /* *

急,关于DataRowView作为属性绑定的问题,求大神帮忙

问题描述 我有一个A类ClassA:INotifyPropertyChanged{publicDataRowViewRowView{get{...}set{...OnPropertyChanged("RowView")}}}有个ObservableCollection<A>的集合绑定到DataGrid绑定的时候列用RowView[列名]banding数据能出来但修改某一行A中的RowView的时候,界面上的值不会刷新求大神帮忙看看是什么原因我在编辑界面调整数据的时候,传了个

c# 自定义propertygrid属性绑定数组,显示问题

问题描述 我添加的数组是这样的效果:需要的效果是这样:谢谢,怎么搞 解决方案 解决方案二:本帖最后由 bdmh 于 2015-11-26 10:39:33 编辑解决方案三:没改过,你看看这篇文章是否有启发http://blog.csdn.net/luyifeiniu/article/details/5426960解决方案四:[TypeConverter(typeof(ExpandableObjectConverter))]structPerson{privateinta,b,c,d;public

Android绑定添加了注解的控件,及其事件方法

  Android绑定添加了注解的控件,及其事件方法.根据成员方法的注解进行绑定,根据成员变量的注解进行绑定,设置事件的监听器,对控件赋值,注意:它必须在activity调用了setContentView之后调用.

Vuejs——(3)计算属性,样式和类绑定

先上总结: (十九)标签和API总结(2) vm指new Vue获取的实例   ①当dom标签里的值和data里的值绑定后,更改data对应的值可以实时更新标签里的值:   但后续添加的值是无效的(绑定失败).   ②将可以将对象直接作为data的一个属性,是有效的(因为对象按值传递): 所以该属性和该对象是全等的:   ③vm的接口有: vm.$data是vm的data属性: vm.$el是el属性指向的dom结点: vm.$watch是监视属性变化(比如data里的值)(参照(九))   ④

WPF中TextBox绑定Double类型数据,TextBox.Text属性不显示空格,光标也不对

问题描述 最近学习WPF遇到一个郁闷的问题:我在前台的TextBox的Text属性绑定了后台一个Double类型的数据,mode=TwoWay,UpdateSourceTrigger=PropertyChanged,这样前台数值变更就会通知到后台,但是存在一个问题,如果我在数字前端或者末尾不停的输入空格,后台绑定的内容还是原来的数值不变,但是前台的空格确实存在.在后台取值时,我需要判断光标的位置是否已经是末尾了,如果使用tbPositionCursor.Select(tbPositionCurs

【lombok】lombok---帮你简化生成必要但臃肿的java代码工具 【映射注解和lombok注解同时使用 以及 映射注解放在属性和get方法上的区别】

官方地址:https://projectlombok.org/ GitHub:https://github.com/rzwitserloot/lombok 指导说明文档:http://jnb.ociweb.com/jnb/jnbJan2010.html =============================================================================================================== 本来来说,lombok