利用Java 动态代理,自定义注解 读取配置文件中的属性值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Java_HuiLong/article/details/85649165

Java动态代理在一些中间件中经常用到,或者一些大型项目中都会用到。
这里顺带使用一下自定义注解方式,基于java 反射机制读取.properties格式文件。

demo的大致内容包含以下:
在这里插入图片描述

1.配置文件:config.properties

url=http://www.hrsstd.com
password= root
username= zhanghuilong
port = 8080
isOpen = true

2.自定义注解类

注解中的原生标签具体含义可以自行了解

/**
 * @author zhanghuilong
 * @desc 自定义注解,读取配置文件内容
 * @since 2019/01/02
 */
@Target({ ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ReadConf {
    /**
     * read config.properties context eg: key = value
     * @return
     */
    String value();

}

3.demo接口定义

/**
 * @author zhanghuilong
 * @desc  配置中心
 * @since 2019/01/02
 */
public interface HrsConfigService {

    @ReadConf(value = "url")
    String  getUrl();

    @ReadConf("password")
    String getPwd();

    @ReadConf("username")
    String getUserName();

    @ReadConf("port")
    Integer getPort();

    @ReadConf("isOpen")
    Boolean getOff();
}

4.动态代理核心实现
invocationHandler的实现


/**
 * @author zhanghuilong
 * @desc 动态代理具体实现方法
 * @since 2019/01/02
 */
public class PropertyInvocationHandler implements InvocationHandler {

    private Properties properties;

    public PropertyInvocationHandler(Properties properties) {
        this.properties = properties;
    }

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

        System.out.println(" 调用 method = [" + method.getName() +"]");
        ReadConf readConf = method.getAnnotation(ReadConf.class);
        if (readConf == null){
            return null;
        }
        String value = readConf.value();
        String property = properties.getProperty(value);
        if (StringUtils.isEmpty(property)){
            return null;
        }

        Class<?> returnClass = method.getReturnType();
        // 基本原始类型,这里只写了部分类型,满足当前demo接口返回值类型,如遇项目有多重类型,可以添加补全所以类型
        if (returnClass.isPrimitive()){
            if (returnClass.equals(int.class)){
                return Integer.valueOf(property);
            }
            else if (returnClass.equals(long.class)){ return (Long.valueOf(property));}
            else if (returnClass.equals(double.class)) {return (Double.valueOf(property));}
            else if (returnClass.equals(float.class)) { return (Float.valueOf(property)); }
            else if (returnClass.equals(boolean.class)) { return (Boolean.valueOf(property));}
        }else {
            if (returnClass.equals(Integer.class)){
                return Integer.valueOf(property);
            }else if (returnClass.equals(String.class)){
                return String.valueOf(property);
            }else if (returnClass.equals(Boolean.class)){
                return Boolean.valueOf(property);
            }
        }

        return property;
    }
}

5.读取配置的通用工厂方法

/**
 * @author zhanghuilong
 * @desc 读取配置工厂方法
 * @since 2019/01/02
 */
public class HrsConfigFactory {

    public HrsConfigFactory() {
    }

    /**
     * 读取方法
     * @param inputStream
     * @return
     */
    public static HrsConfigService readProperties(final InputStream inputStream){

        final Properties properties = new Properties();
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            System.out.println("load inputStream error ");
            return null;
        }
        
        // java 代理机制
        return  (HrsConfigService)Proxy
            .newProxyInstance(HrsConfigService.class.getClassLoader(), new Class[] { HrsConfigService.class },
                new PropertyInvocationHandler(properties));
    }
}

6.demo 的测试执行类main方法

/**
 * @author zhanghuilong
 * @desc 动态代理+自定义注解
 * @since 2019/01/02
 */
public class DemoTest {

    public static void main(String[] args) {

    try {
        // 文件地址可以直接copypath
        InputStream fileInputStream = new FileInputStream("/Users/zhanghuilong/demo/config.properties");
        HrsConfigService configService = HrsConfigFactory.readProperties(fileInputStream);
        if (configService == null){
            return;
        }
        Integer port = configService.getPort();
        String url = configService.getUrl();
        String userName = configService.getUserName();
        String pwd = configService.getPwd();
        Boolean off = configService.getOff();
        String format = String.format("读取配置信息,url: %s, username: %s, password: %s, port :%s, 开关:%s",
            url, userName, pwd, port, off);

        System.out.println( format );
    } catch (FileNotFoundException e) {
        System.out.println("文件不存在");
    }

    }
}

输出:

 调用 method = [getPort]
 调用 method = [getUrl]
 调用 method = [getUserName]
 调用 method = [getPwd]
 调用 method = [getOff]
读取配置信息,url: http://www.hrsstd.com, username: zhanghuilong, password: root, port :8080, 开关:true

本文主要想简单说明下 java 动态代理在实际工作中的应用 和实践。

猜你喜欢

转载自blog.csdn.net/Java_HuiLong/article/details/85649165