博客
关于我
Java基础--Annotation
阅读量:505 次
发布时间:2019-03-07

本文共 5069 字,大约阅读时间需要 16 分钟。

Annotation设值/取值与反射实现工厂模式

1. 其他网址(无关内容已移除)

2. 注解设值/取值

1. 简介

注解可以用于设定或获取对象的属性值,支持单个对象或数组类型。通过注解,可以为属性设定枚举类型的值。

2. 实例

以下是一个使用注解定义枚举类型并实现动态设值的示例:

package org.example.a;import java.lang.annotation.*;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@Documented@interface Parent {    Color[] value() default {};}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@Documented@interface Bottom {    String name() default "";}enum Color {    RED,    @Bottom(name = "浅红色")    @Parent({RED})    LIGHT_RED,    @Bottom(name = "深红色")    @Parent({RED, LIGHT_RED})    DARK_RED;    List childrens = new ArrayList();    static List bottoms = new ArrayList();    static {        for (Color value : Color.values()) {            try {                Field field = Color.class.getField(value.name());                if (field.isAnnotationPresent(Bottom.class)) {                    bottoms.add(value);                }                Parent parent = field.getAnnotation(Parent.class);                if (parent != null) {                    for (Color color : parent.value()) {                        color.childrens.add(value);                    }                }            } catch (NoSuchFieldException e) {                e.printStackTrace();            }        }    }}public class Demo {    public static void main(String[] args) {        System.out.println("Color.RED.childrens:         " + Color.RED.childrens);        System.out.println("Color.LIGHT_RED.childrens:   " + Color.LIGHT_RED.childrens);        System.out.println("Color.bottoms:               " + Color.bottoms);                try {            Field field = Color.class.getField(Color.LIGHT_RED.name());            if (field.isAnnotationPresent(Bottom.class)) {                System.out.println("Color.LIGHT_RED的注解属性名: " +                        field.getAnnotation(Bottom.class).name());            }        } catch (NoSuchFieldException e) {            e.printStackTrace();        }    }}

3. 执行结果

执行上述代码后,输出结果如下:

Color.RED.childrens:         [LIGHT_RED, DARK_RED]Color.LIGHT_RED.childrens:   [DARK_RED]Color.bottoms:               [LIGHT_RED, DARK_RED]Color.LIGHT_RED的注解属性名: 浅红色

4. Annotation+反射实现工厂模式

1. 简介

通过注解和反射机制,可以轻松实现工厂模式,动态地根据注解指定的实现类获取对象实例。这对需要灵活配置服务实现的场景非常有用。

2. 需求

创建一个能够根据注解指定的实现类来获取对应的业务实例。

3. 代码实现

以下是一个使用注解和反射实现工厂模式的例子:

package org.example.a;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;// 业务接口interface IMessage {    public void send(String msg);}// 业务接口实现子类class IMessageImpl1 implements IMessage {    @Override    public void send(String msg) {        System.out.println("send(IMessageImpl1): " + msg);    }}// 业务接口实现子类class IMessageImpl2 implements IMessage {    @Override    public void send(String msg) {        System.out.println("send(IMessageImpl2): " + msg);    }}// 工厂类class Factory {    private Factory() {}    public static 
T getInstance(Class
clazz) { try { return (T) new MessageProxy().bind(clazz.getDeclaredConstructor().newInstance()); } catch (Exception e) { return null; } }}// 逆向代理类class MessageProxy implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public boolean connect() { System.out.println("connect(proxy)"); return true; } public void close() { System.out.println("close(proxy)"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (this.connect()) { return method.invoke(this.target, args); // 代理调用 } else { throw new Exception("cannont send"); } } finally { this.close(); } }}// 使用注解定义要使用的实现类@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)interface UseMessage { // 定义要使用的类型 public Class
clazz();}// 使用注解指定实现类@UseMessage(clazz = IMessageImpl1.class)class MessageService { private IMessage message; // 初始化业务处理 public MessageService() { UseMessage use = MessageService.class.getAnnotation(UseMessage.class); this.message = (IMessage) Factory.getInstance(use.clazz()); } public void send(String msg) { this.message.send(msg); }}// 运行测试类public class Demo { public static void main(String[] args) { MessageService messageService = new MessageService(); messageService.send("www.sina.com.cn"); }}

4. 执行结果

执行上述代码后,输出结果如下:

connect(proxy)send(IMessageImpl1): www.sina.com.cnclose(proxy)

这个示例展示了如何通过注解和反射机制实现工厂模式。通过注解指定需要使用的实现类,工厂类负责根据注解信息创建相应的实例。这种方法动态、灵活,适合需要根据不同配置或环境选择实现类的场景。

转载地址:http://zytjz.baihongyu.com/

你可能感兴趣的文章
Netty源码—8.编解码原理二
查看>>
Netty源码解读
查看>>
Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
查看>>
Netty相关
查看>>
Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
查看>>
Network Sniffer and Connection Analyzer
查看>>
NetworkX系列教程(11)-graph和其他数据格式转换
查看>>
Networkx读取军械调查-ITN综合传输网络?/读取GML文件
查看>>
Net与Flex入门
查看>>
net包之IPConn
查看>>
NFinal学习笔记 02—NFinalBuild
查看>>
NFS共享文件系统搭建
查看>>
nfs复习
查看>>
NFS网络文件系统
查看>>
nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
查看>>
ng 指令的自定义、使用
查看>>
Nginx
查看>>
nginx + etcd 动态负载均衡实践(二)—— 组件安装
查看>>
nginx + etcd 动态负载均衡实践(四)—— 基于confd实现
查看>>
Nginx + Spring Boot 实现负载均衡
查看>>