jms---两个应用程序之间需要进行通信,我们使用一个JMS服务,进行中间的转发,通过JMS 的使用,我们可以解除两个程序之间的耦合
发布JmsTemplate--需要Destination(目的地)
监听MessageListener---onMessage(Message message)
@PostConstruct基本:
@PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。
Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
业务场景:
都需要继承某一接口, 存在不同对象,作出不同响应,在中间层处理业务,但是可以通过不同的对象 实现不同的响应,需要在最底层给出各种消息的实例
例如jms中消息的监听
public abstract class MsgListenerMiddle implements MessageListener {
private Map<String, MsgHandler<? extends Msg>> msgParsers;
public MsgListenerSupport() {
msgParsers = new HashMap<String, MsgHandler<? extends Msg>>();
init();
}
@PostConstruct
public abstract void init();
protected void registerMsgHandler(Class<? extends Msg> msgType, MsgHandler<? extends Msg> msgHandler) {
msgParsers.put(msgType.getName(), msgHandler);
}
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
String messageType = message.getJMSType();
Class<? extends Msg> msgType = (Class<? extends Msg>) ClassUtils.getClass(messageType);
Msg msg = JSONUtils.fromJson(textMessage.getText(), msgType);
MsgHandler msgParser = msgParsers.get(msgType.getName());
if (msgParser == null) {
System.out.println("实例 (" + msgType.getName() + ") 未找到,请注册");
return;
}
msgParser.handleMsg(msg);
} catch (JMSException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
public class MsgListener extends MsgListenerMiddle {
/** 线程池 */
private ThreadPool threadPool;
private final static Logger log = UtilProperties.instance.getLogger(MsgListener.class);
public MsgListener() {
threadPool = new ThreadPool(UtilProperties.instance.getThreadPool());
}
@Override
public void init() {
registerMsgHandler(UserMsg.class, new UserMsgParser());
}
public class UserMsgParser implements MsgHandler<UserMsg> {
@Override
public void handleMsg(final UserMsg userMsg) {
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
UserService.getInstance().sendEmail(userMsg.getUsername(), chargeMsg);
}
});
}
}
//继续下一个消息类型 implements MsgHandler<xxx>
public class xxxMsgParser implements MsgHandler<xxxMsg> {
@Override
public void handleMsg(final xxxMsg xxxMsg) {
}
}
}
public interface MsgHandler<T extends Msg> {
@LogIgnore
void handleMsg(T msg);
}
//Msg就直接写在这了 仅仅用于抽象
public interface Msg extends Serializable {}
主要梳理地方在于MsgListenerMiddle 类中 抽象两处 MsgHandler Msg 所以需要这两个的具体实例 相当于在 MsgListenerMiddle msgParser.handleMsg(msg);这句代码需要被抽象, 就能实现 不同实例做出不同的响应
final修饰参数 引用类型,这时可以改变值,但是不能重新赋值,引用类型变量所指的引用是不能够改变的,但是引用类型变量的值是可以改变的
public void testReferenceType(final Student stu){