Java注解的使用

注解一般可以当成配置使用。

之前已经用过配置,比如propeties配置文件。

案例:

设计一个水果类

package com.njwbhz.newssys.annotation;

public class Apple {
    private String address;//产地
    private String brand;//品牌
    private double price;//价格

    public Apple() {
    }

    public Apple(String address, String brand, double price) {
        this.address = address;
        this.brand = brand;
        this.price = price;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "address='" + address + '\'' +
                ", brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

传统的使用Apple的方式;

package com.njwbhz.newssys.annotation;

public class TestApple {
    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.setAddress("山东烟台");
        apple.setBrand("红富士");
        apple.setPrice(10);
        System.out.println(apple);
        /*
        数据硬编码在程序中
        (直接写到代码中)
        问题:如果这些数据需要频繁修改
        只能频繁的修改java文件
        ——>重新编译生成class文件
        ——>先停服务器
        ——>在服务器上做替换——>十分麻烦
         */
    }
}

把频繁要修改的数据提取到配置文件中,比如db.properties

采用配置文件的方式,让程序更加灵活。

src/apple.properties

address = 山东烟台
brand = 红富士
price = 10

使用配置文件

package com.njwbhz.newssys.annotation;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class AppleFactory {
    private static Map<String , String> dataMap = new HashMap<String, String>();

    static {
        //解析apple.properties文件//
        BufferedReader reader = null;
        reader = new BufferedReader(new InputStreamReader(AppleFactory.class.getClassLoader().getResourceAsStream("apple.properties")));
        try {
            String lineData = reader.readLine();
            String [] datas = null;
            String fileName = null;//属性名,和apple中的属性一致
            String fileValue = null;//属性值
            while (null != lineData) {
                datas = lineData.split("=");
                fileName = datas[0].trim();
                fileValue = datas[1].trim();
                dataMap.put(fileName , fileValue);
                lineData = reader.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static Apple newInstance () {
        Apple apple = new Apple();
        //数据来自配置文件,通过反射的方式动态设置
        set(apple);
        return apple;
    }

    private static void set (Apple apple) {
        Class clazz = apple.getClass();
        //通过反射设置值
        Set<Map.Entry<String, String>> entries = dataMap.entrySet();
        Iterator<Map.Entry<String, String>> it = entries.iterator();
        while (it.hasNext()) {
            Map.Entry<String , String> entry = it.next();
            //entry.key——>属性名   enyrty.getKey()——>value值
            try {
                Field field = clazz.getDeclaredField(entry.getKey());
                String methodName = "set" + entry.getKey().substring(0 , 1).toUpperCase() + entry.getKey().substring(1);
                Method method = clazz.getMethod(methodName , field.getType());
                if (entry.getKey().equals("price")) {
                    method.invoke(apple , Double.valueOf(entry.getValue()));
                } else {
                    method.invoke(apple , entry.getValue());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

测试

package com.njwbhz.newssys.annotation;

public class TestApple {
    public static void main(String[] args) {
        Apple apple = AppleFactory.newInstance();
        System.out.println(apple);
    }
}

 

出现乱码的解决方案:

 

重新编写配置文件的value

配置的关键点:解析配置文件、使用配置文件中数据做相关处理(技巧:反射)。

使用注解做配置,注解的保留策略:RUNTIME,程序运行时候获取注解,最后利用注解做处理。

设计注解:

package com.njwbhz.newssys.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Address {
    String value() default "";
}

package com.njwbhz.newssys.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Brand {
    String value() default "";
}

package com.njwbhz.newssys.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Price {
    double value() default 0.0;
}

使用注解

package com.njwbhz.newssys.annotation;

public class Apple {
    @Address("阿克苏")
    private String address;//产地
    @Brand("红富士")
    private String brand;//品牌
    @Price(20)
    private double price;//价格

    public Apple() {
    }

    public Apple(String address, String brand, double price) {
        this.address = address;
        this.brand = brand;
        this.price = price;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "address='" + address + '\'' +
                ", brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

解析注解,使用反射技术。

package com.njwbhz.newssys.annotation;

import java.lang.reflect.Field;

public class AppleFactoryByAnnotation {
    public static Apple newInstance () {
        Apple apple = new Apple();
        //apple中的值,使用注解中的配置信息
        Class clazz = apple.getClass();
        //注解是作用在属性上,反射将属性封装成了Field对象
        //反射——>获取所有的属性Field——>Field获取相关的注解
        Field [] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //field可能是address,也可能是brand,也可能是price
            String fieldName = field.getName();
            if (fieldName.equals("address")) {
                //获取@Address
                Address addressAnnotation = field.getAnnotation(Address.class);
                //获取对应的成员的信息
                String value = addressAnnotation.value();
                apple.setAddress(value);
            } else if (fieldName.equals("brand")) {
                //获取@Brand
                Brand brandAnnotation = field.getAnnotation(Brand.class);
                //获取对应的成员的信息
                String value = brandAnnotation.value();
                apple.setBrand(value);
            } else if (fieldName.equals("price")) {
                //获取@Price
                Price priceAnnotation = field.getAnnotation(Price.class);
                //获取对应的成员的信息
                double value = priceAnnotation.value();
                apple.setPrice(value);
            }
        }
        return apple;
    }
}

测试:

package com.njwbhz.newssys.annotation;

public class TestApple {
    public static void main(String[] args) {
//        Apple apple = AppleFactory.newInstance();
//        System.out.println(apple);
        Apple apple = AppleFactoryByAnnotation.newInstance();
        System.out.println(apple);
    }
}

 

结论:注解可以做程序的配置

对比:

结论:注解做程序的配置是现代软件开发的主流。

真正的配置采用配置文件 + 注解 协同工作。                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FairyKunKun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值