当前位置: 首页 > wzjs >正文

家具网站设计网自适应网站制作费用

家具网站设计网,自适应网站制作费用,免费的wordpress分类在哪设置,网站制作的地方从责任链模式聊到aware接口 责任链是什么? 责任链模式是一种行为型设计模式,将多个对象连接成一条链,并且沿着这条链传递请求,让多个对象都有机会处理这个请求,请求会顺着链传递,直到某个对象处理它为止。…

从责任链模式聊到aware接口

责任链是什么?

责任链模式是一种行为型设计模式,将多个对象连接成一条链,并且沿着这条链传递请求,让多个对象都有机会处理这个请求,请求会顺着链传递,直到某个对象处理它为止。

它主要避免了请求发送者和接受者之间的耦合,增强了系统的灵活性和可扩展性。

责任链模式的特点:

  1. 解耦请求发送者与接收者:请求发送者无需知道请求是由哪个处理器处理的。

  2. 动态组合处理器:可以灵活地动态改变链的结构。

  3. 请求沿链传递:请求可以由链中的一个或多个处理器处理。

一般用在什么场景?

  1. 请求需要多个处理器:例如日志记录的不同级别处理。

  2. 动态指定处理流程:请求的处理方式不固定,依赖于运行时的链条结构。

  3. 消除条件分支:用责任链代替代码中的 if-elseswitch-case 语句。

我们先来看一个责任链模式的简易版代码

// 处理器接口
abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(String request);
}// 具体处理器A
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("ConcreteHandlerA handled request: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);} else {System.out.println("No handler for request: " + request);}}
}// 具体处理器B
class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("ConcreteHandlerB handled request: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);} else {System.out.println("No handler for request: " + request);}}
}// 客户端
public class Main {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();handlerA.setNextHandler(handlerB);handlerA.handleRequest("A"); // Output: ConcreteHandlerA handled request: AhandlerA.handleRequest("B"); // Output: ConcreteHandlerB handled request: BhandlerA.handleRequest("C"); // Output: No handler for request: C}
}

看完这个代码,可能很多人会觉得很简单,但这里我抛出两个问题

1.这不就是一个面向对象的一个思想吗,把责任链的判断逻辑封装成对象?那为何叫做责任链模式

2.这抛开“OOP”的解耦,真的做到了进一步解耦吗?

好我们来逐一解答:

问题一:

我觉得这就是责任链模式,责任链模式是一种行为型设计模式,将多个对象连接成一条链。把行为封装成对象既是责任链的定义也是oop的思想。

问题二:

我觉得解耦度还不够,因为假设这个时候需要加一个责任链判定点。有两种做法

1.直接在ConcreteHandlerA orB里面去填加代码

2.写一个ConcreteHandlerN,然后在对应的接口把ConcreteHandlerN加进去

不难发现,这里的两种方法都要去修改已经写好的代码,这是不太完美的

所以我们要对这个责任链进行改进,引入一个东西 ApplicationContextAware

ApplicationContextAware

可能对spring不太熟悉的人不知道这是什么,我们先简单介绍一下

ApplicationContextAware 是 Spring 框架中的一个核心接口,用于让 Bean 感知到 Spring 应用上下文(ApplicationContext),从而能够与容器进行交互。以下是它的核心概念

关键能力

  • 访问容器资源:通过 ApplicationContext 获取其他 Bean、环境变量、国际化消息等。

  • 监听容器事件:可以注册监听器(ApplicationListener)响应容器事件(如上下文刷新、关闭等)。

  • 动态控制容器行为:例如动态注册新 Bean 或修改 Bean 定义。

我们怎么使用ApplicationContextAware到责任链中

这里我们使用了他的第一个能力

访问容器资源:通过 ApplicationContext 获取其他 Bean、环境变量、国际化消息等

 
public final class MerchantAdminChainContext<T> implements ApplicationContextAware, CommandLineRunner {private ApplicationContext applicationContext;
​ private final Map<String, List<MerchantAdminAbstractChainHandler>> abstractChainHandlerContainer = new HashMap<>();
@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}Map<String, MerchantAdminAbstractChainHandler> chainFilterMap = applicationContext.getBeansOfType(MerchantAdminAbstractChainHandler.class);//以下就是根据责任链上的一些属性,比如mark(声明是干嘛的),order(优先级)、用一个map按标记分组,按order排序//然后再写一个hander调用bean对责任链判断就ok了
}

applicationContext.getBeansOfType(MerchantAdminAbstractChainHandler.class);这个方法要记住,这个方法获取了责任链接口下的所有实现类,String 类型的键(Key)表示 Bean 的名称,而 T 类型的值(Value)是对应的 Bean 实例。

那我们怎么使用

 private final MerchantAdminChainContext merchantAdminChainContext;@Overridepublic void createCouponTemplate(CouponTemplateSaveReqDTO requestParam) {merchantAdminChainContext.handler(ChainBizMarkEnum.MERCHANT_ADMIN_CREATE_COUPON_TEMPLATE_KEY.name(), requestParam);

代码解疑

可能有朋友不清楚MerchantAdminChainContext<T>为什么会 implements CommandLineRunner,这是干嘛的

CommandLineRunner 在这里的用途是 在 Spring Boot 应用启动完成后立即执行初始化逻辑

核心作用

  • 延迟初始化:在 Spring 上下文完全加载后(所有 Bean 初始化完成),才执行责任链处理器的扫描、分组和排序操作。

  • 确保 Bean 就绪:保证 applicationContext.getBeansOfType(...) 能获取到完整的 Bean 集合,避免因 Bean 未初始化导致的空指针问题。

现在回头看第二个问题,这样还耦合吗? 我们在创建优惠券模块(这里假设场景是对优惠券创建合法性的判断)只用到了MerchantAdminChainContext,而如果想要假如新的判断逻辑只需要继续写一个类去实现MerchantAdminAbstractChainHandler就ok了,耦合度相当低。

但是我们可以看到implements ApplicationContextAware之后我们还是调用了ApplicationContext applicationContext;那我能不能直接用ApplicationContext。

这里我觉得答案是可以的

那我为什么要先说ApplicationContextAware的方案呢,因为我初学这个用法的时候是学的网上一个比较火的项目,他是这么写的

我们先看看

ApplicationContextAware与注入ApplicationContext的差异

​维度​**ApplicationContextAware**​**@Autowired**
​调用时机在Bean初始化后由Spring容器主动调用setApplicationContext在构造函数或@PostConstruct后注入
​适用场景需要动态获取Bean(如插件化、运行时决策)常规依赖注入,Bean已被Spring管理
​代码耦合度需实现接口,增加少量代码冗余更简洁,符合Spring最佳实践
​内存泄漏风险需注意避免静态持有ApplicationContext无此风险
为何有时必须用ApplicationContextAware
  • 非Spring类:无法使用@Autowired,必须通过接口或手动传递上下文。

  • 容器初始化前访问:如Filter的init方法,此时依赖注入尚未完成。

  • 静态上下文访问:若需静态方法访问容器(如工具类),必须通过ApplicationContextAware或单例持有上下文。

为什么ApplicationContextAware能获取

以一个实现了ApplicationContextAware的Bean为例,流程如下:

  1. Bean实例化:Spring通过构造函数创建Bean实例。

  2. 属性填充:填充Bean的依赖属性(如@Autowired注入的字段)。

  3. BeanPostProcessor处理:

    1. ApplicationContextAwareProcessor在属性填充后、初始化方法(如@PostConstruct)执行前被调用。

    2. 检测Bean是否实现了ApplicationContextAware,若是,则调用setApplicationContext注入上下文。

  4. 初始化完成:执行@PostConstruct方法或自定义初始化逻辑。

class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(applicationContext);}return bean;}
}

Spring的Bean生命周期中,BeanPostProcessor接口允许在Bean初始化前后插入自定义逻辑。ApplicationContextAware的实现依赖于一个特殊的BeanPostProcessor:**ApplicationContextAwareProcessor**。

  • ApplicationContextAwareProcessor的作用: 在Bean实例化完成后、属性填充之前,检查该Bean是否实现了ApplicationContextAware接口。如果是,则在后续流程中调用其setApplicationContext方法。

  • 源码位置org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory类中的populateBean方法会调用invokeAwareMethods,进而触发ApplicationContextAwareProcessor的逻辑。

再说说实例化与初始化的区别吧

看看代码

@Component
public class OrderService {private String orderId;// 实例化:Spring调用构造函数public OrderService() {System.out.println("实例化:OrderService构造函数");}// 初始化:依赖注入(属性填充)@Autowiredpublic void setOrderId(String orderId) {this.orderId = orderId;System.out.println("初始化:依赖注入orderId");}// 初始化:@PostConstruct方法@PostConstructpublic void init() {System.out.println("初始化:@PostConstruct方法");}
}

可能有人不知道初始化到底是干什么的可以在看看【为什么要指定bean的初始化方法直接调用不香吗】https://www.bilibili.com/video/BV1aJ4m1b7cZ?vd_source=f12c29722f73a19d4d78325e01363bcb


文章转载自:

http://fEJmlaVn.ywpwq.cn
http://6mnJGa2t.ywpwq.cn
http://3AO703Xv.ywpwq.cn
http://03XJH5IE.ywpwq.cn
http://pcxZbt0D.ywpwq.cn
http://gALYwRq8.ywpwq.cn
http://CcazbL9H.ywpwq.cn
http://8r77I6VX.ywpwq.cn
http://DxqXWmYV.ywpwq.cn
http://5Xcn4z3F.ywpwq.cn
http://niMTs1CV.ywpwq.cn
http://7EWk6DbN.ywpwq.cn
http://2rzyMhtE.ywpwq.cn
http://BroiVkrj.ywpwq.cn
http://4oM3DMJa.ywpwq.cn
http://FCS1II7S.ywpwq.cn
http://UyXOmlKz.ywpwq.cn
http://oUCiZ5Yv.ywpwq.cn
http://zme4vGcd.ywpwq.cn
http://Ytjwi5NY.ywpwq.cn
http://5eNsX6Mh.ywpwq.cn
http://5vavWfK4.ywpwq.cn
http://Ht8aqPtb.ywpwq.cn
http://uux66jOa.ywpwq.cn
http://yKz1faGq.ywpwq.cn
http://SiZy5yjh.ywpwq.cn
http://CvLDb5aU.ywpwq.cn
http://oM82nLN9.ywpwq.cn
http://8vSz8lqW.ywpwq.cn
http://s6sscG01.ywpwq.cn
http://www.dtcms.com/wzjs/636398.html

相关文章:

  • 良庆网站建设教做面食的网站
  • 学校网站制作多少钱临沂网站建设找谁
  • 淳安千岛湖建设集团网站弄一个网站要多少钱
  • 开服表网站开发微信公众号申请注册官网
  • 中文儿童网站模板建设通网站是什么性质
  • 网站建设环境搭建心得体会49图库下浏览器
  • 信用门户网站建设观摩网站开发电子商务
  • 做的网站打开慢宠物网站模板下载
  • 资源付费网站制作百度免费安装下载
  • 搜索网站排行企业管理咨询有限公司是做什么的
  • 网站建设与网络推广的关系一般做网站需要的js有哪些
  • 哪里卖网站域名那个网站都有做莱的图片
  • easyui做网站去掉wordpress.org
  • 律师网站建设推荐手机网站建设机构
  • 网站做互动coreldraw
  • 室内设计网站排行榜前十名知乎什么叫前端什么叫后端
  • 分享几个x站好用的关键词开发手机app游戏公司
  • 谷歌网站站长指南WordPress主题Cute主题
  • wordpress 缓存腾讯cos贵州百度seo整站优化
  • 海口房产网站建设seo排名优化是什么
  • php网站制作常用代码网页制作与网站开发从入门到精通 豆瓣
  • 河池企业网站开发公司昆明网站建设技术托管
  • 想找个人建网站商业网站需要多少钱
  • 网站运维工作内容天然气公司的网站应该怎么做
  • 动漫网站开发 sh框架66郑州网站建设
  • 1万元可以注册公司吗wordpress 优化数据
  • 怎样做一个购物型的网站开发一套小程序多少钱
  • 做ppt的素材免费网站建网站备案需要的材料
  • 网站的留言怎么做有哪些app软件开发公司
  • 东莞网站网络推广公司ps做网站浏览器预览