原文:https://blog.csdn.net/Dwade_mia/article/details/78883045
工厂模式
通过AbstractAutowireCapableBeanFactory继承抽象工厂AbstractBeanFactory
实现的功能:创建(实例化和初始化bean),装配(包括自动装配)、销毁。
单例模式
spring创建的bean默认为singleton
适配器模式
比如说Springmvc的HandlerInterceptorAdapter就是个接口适配器,实现了AsyncHandlerInterceptor(HandlerInterceptor的子类),只需要重写关注方法即可,不相关的方法完全可以忽略。
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
@Override
public void afterConcurrentHandlingStarted(
HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}
public class ThemeChangeInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
// do somethings
}
}
个人认为用得最好的地方莫过于spring-jms的MessagingMessageListenerAdapter,在onMessage中将jsm的Message转换为message模块的Message对象(内部类的LazyResolutionMessage,重写了getPayload、getHeader),并交给message模块的InvocableHandleMethod,这样一来便可以实现jms与spring message无缝适配对接了,在spring-websocket也是相同的套路
public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageListener {
private InvocableHandlerMethod handlerMethod;
public void setHandlerMethod(InvocableHandlerMethod handlerMethod) {
this.handlerMethod = handlerMethod;
}
@Override
public void onMessage(javax.jms.Message jmsMessage, Session session) throws JMSException {
Message<?> message = toMessagingMessage(jmsMessage);
if (logger.isDebugEnabled()) {
logger.debug("Processing [" + message + "]");
}
Object result = invokeHandler(jmsMessage, session, message);
if (result != null) {
handleResult(result, jmsMessage, session);
}
else {
logger.trace("No result object given - no result to handle");
}
}
protected Message<?> toMessagingMessage(javax.jms.Message jmsMessage) {
try {
return (Message<?>) getMessagingMessageConverter().fromMessage(jmsMessage);
}
catch (JMSException ex) {
throw new MessageConversionException("Could not convert JMS message", ex);
}
}
// 忽略部分代码
}
jms:
spring提供了一个jms集成框架,这个框架如spring 集成jdbc api一样,简化了jms api的使用。
jms可以简单的分成两个功能区,消息的生产和消息的消费。JmsTemplate类用来生成消息和同步接受消息。和其它java ee的消息驱动样式一样,对异步消息,spring也提供了许多消息监听容器用来创建消息驱动的POJO(MDPs)。
装饰模式
装饰模式是指在不影响其它类的情况下,动态透明的扩展一个对象的功能,比如TransactionAwareCacheDecorator增加了对事务的支持,在事务提交、回滚的时候分别对Cache的数据进行处理。
public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
public TransactionAwareCacheDecorator(Cache targetCache) {
Assert.notNull(targetCache, "Target Cache must not be null");
this.targetCache = targetCache;
}
@Override
public void put(final Object key, final Object value) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
targetCache.put(key, value);
}
});
}
else {
this.targetCache.put(key, value);
}
}
// 忽略部分代码
}
观察者模式
在spring中我们借助ApplicationListener、ApplicationEventPublisher便可以完成简直的事件通知。当调用ApplicationEventPublisher#publishEvent()时,spring会查找实现了ApplicationListener接口、并且使用了指定泛型的bean,然后调用其onApplicationEvent。下面的代码示范了spring发出ContextRefreshedEvent事件。
ApplicationEventPublisher eventPublisher = xxx;
eventPublisher.publishEvent( new ContextRefreshedEvent( applicationContext ) );
public class TestListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// invoke after spring context refreshed
}
}
责任链模式
比如SpringMVC的HandlerExecutionChain通过本身的构造方法将interceptor拦截器赋值,然后对请求进行拦截处理。
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private int interceptorIndex = -1;
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
}
建设者模式(Builder)
为了简化对象的创建过程而使用的一种设计模式,比如BeanDefinitionBuilder是为了简化BeanDefinition的创建过程,每次setXXX都会返回BeanDefinitionBuilder实例,方便以链条编码的方式创建BeanDefinitionBuilder
public class BeanDefinitionBuilder {
public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass) {
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition();
builder.beanDefinition.setBeanClass(beanClass);
return builder;
}
private AbstractBeanDefinition beanDefinition;
public BeanDefinitionBuilder addConstructorArgValue(Object value) {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, value);
return this;
}
public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}
}
模板模式
spring中很多地方会这样做,在一个方法里面完成了一小部分逻辑,然后接着调用一个或多个抽象方法,而这个抽象方法需要由子类重写,比如AbstractApplicationContext里面的refresh()、getBeanFactory()等等,这样便可以很好的提高了程序的扩展性
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。