使用注解“Annotation"进行开发的最大特点是可以将相应的配置信息写入Annotation后,在项目启动时通过反射获取相应注解Annotation定义并进行操作。
1、Annotation整合工厂设计模式与代理设计模式的例子:
package com.mydemo;
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;
public class ReflectDemo {
public static void main(String[] args) {
// 实例化接口对象
MessageService messageService = new MessageService();
// 调用方法
messageService.send("这种操作真骚,太TM好用了,就是还没理解精髓");
}
}
// 业务接口
interface IMessage {
// 输入业务
public void send(String msg);
}
// 业务接口实现子类
class CloudMessageImpl implements IMessage {
/**
* 方法覆写
*
* @param msg
*/
@Override
public void send(String msg) {
System.out.println("【云消息发送】" + msg);
}
}
// 业务接口实现子类
class NetMessageImpl implements IMessage {
/**
* 方法覆写
*
* @param msg
*/
@Override
public void send(String msg) {
System.out.println("【网络消息发送】" + msg);
}
}
class Factory {
private Factory() {
}
/**
* 返回实例化对象
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getInstance(Class<T> clazz) {
// 利用反射获取实例化对象
try {
return (T) new MessageProxy().bind(clazz.getDeclaredConstructor().newInstance());
} catch (Exception e) {
return null;
}
}
}
@Target({ElementType.TYPE, ElementType.METHOD}) // 只能用在类和方法上
@Retention(RetentionPolicy.RUNTIME)
@interface UseMessage {
// 定义要使用的类型
public Class<?> clazz();
}
// 注解Annotation定义实用类
//@UseMessage(clazz = CloudMessageImpl.class)
@UseMessage(clazz = NetMessageImpl.class)
class MessageService {
// 定义业务处理类
private IMessage iMessage;
/**
* 无参构造方法
*/
public MessageService() {
UseMessage useMessage = MessageService.class.getAnnotation(UseMessage.class);
this.iMessage = (IMessage) Factory.getInstance(useMessage.clazz());
}
/**
* 发送方法
*
* @param msg
*/
public void send(String msg) {
this.iMessage.send(msg);
}
}
// 代理类
class MessageProxy implements InvocationHandler {
private Object target;
/**
* 对象绑定
*
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
/**
* 代理方法
*
* @return
*/
public boolean connect() {
System.out.println("[---代理操作---]进行消息发送的通道的链接");
return true;
}
/**
* 代理方法
*/
public void close() {
System.out.println("[---代理操作---]关闭连接通道");
}
/**
* 方法覆写
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@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("【ERROR】消息无法进行发送!!!");
}
} finally {
// 要记得调用这个
this.close();
}
}
}
运行结果:
[---代理操作---]进行消息发送的通道的链接
【网络消息发送】这种操作真骚,太TM好用了,就是还没理解精髓
[---代理操作---]关闭连接通道
思路讲解:本程序先将工厂设计模式与代理设计模式结合在一起,这样可以实现真实业务与代理业务的分割;同时利用工厂类对外隐藏了代理类的操作细节,这样的整合更加符合实际项目开发结构。在本程序中MessageService类要调用IMessage接口提供的send()方法,所以在MessageService类定义上使用类自定义的@UseMessage注解,以确定要使用的IMessage接口子类,如果要进行子类更换,则直接修改注解定义即可。