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

中国社交网站做多外国人的深圳优化排名公司

中国社交网站做多外国人的,深圳优化排名公司,wordpress 不显示首页,建设网贷网站目录 两次匹配 Bean 后置处理器中的匹配 方法调用时的匹配 Bean后置处理器中Advisor匹配流程 方法调用时的匹配 Jdk cglib 小小总结 Advisor 收集与排序 责任链执行过程 两次匹配 Bean 后置处理器中的匹配 在 Bean 初始化过程中,Spring 会通过 Bean 后置…

目录

两次匹配

Bean 后置处理器中的匹配

方法调用时的匹配

Bean后置处理器中Advisor匹配流程

方法调用时的匹配

Jdk

cglib

小小总结

Advisor 收集与排序

责任链执行过程


两次匹配

Bean 后置处理器中的匹配

在 Bean 初始化过程中,Spring 会通过 Bean 后置处理器(BeanPostProcessor)匹配出符合当前 Bean 类型的 Advisor。这一过程主要发生在 postProcessAfterInitialization 方法中。

  • 目的:确定当前 Bean 是否需要代理,以及使用哪些 Advisor。

  • 过程:

  • Spring 会调用 getAdvicesAndAdvisorsForBean 方法,查找所有候选的 Advisor。

  • 过滤出可以应用到当前 Bean 的 Advisor,并将其存储在一个缓存中(如 advisedBeans)。

方法调用时的匹配

在方法调用时,Spring 会根据当前调用的方法和目标对象的类型,从已经匹配的 Advisor 中进一步匹配出符合当前方法的 Advisor。

  • 目的:动态构建拦截器链,以便在方法执行时应用相应的拦截器。

  • 过程:

  • Spring 会调用 getInterceptorsAndDynamicInterceptionAdvice 方法,获取与当前方法匹配的拦截器。

  • 通过切点(Pointcut)进一步过滤出符合当前方法的 Advisor。

Bean后置处理器中Advisor匹配流程

这个流程主要是在spring容器的初始化阶段,下面详细解析一下postProcessAfterInitialization的源码,注释贴在代码上

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {// 根据bean.getClass()和beanName构建缓存keyObject cacheKey = getCacheKey(bean.getClass(), beanName);// 检查bean是否已经被处理if (this.earlyProxyReferences.remove(cacheKey) != bean) {// 如果需要代理,就包装beanreturn wrapIfNecessary(bean, beanName, cacheKey);}}return bean;
}protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 已经处理过的bean直接返回if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}// 跳过特定bean的检查代码...// 为给定bean获取适用的Advisor - 关键步骤!Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);// 如果找到了合适的Advisor,创建代理if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);// 创建代理的核心方法Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;
}
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {// 查找匹配当前bean的AdvisorsList<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();
}protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {// 获取所有候选AdvisorList<Advisor> candidateAdvisors = findCandidateAdvisors();// 过滤出可以应用到当前bean的AdvisorList<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);// 扩展点,子类可以添加自定义的AdvisorextendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {// 排序eligibleAdvisors = sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;
}

方法调用时的匹配

Jdk
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;// 获取被代理的对象TargetSource targetSource = this.advised.getTargetSource();Object target = null;try {// ... 省略一些特殊方法处理逻辑 ...Object retVal;// 处理通用拦截器逻辑if (this.advised.exposeProxy) {// 设置代理到ThreadLocaloldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// 获取目标对象target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);// 获取当前方法的拦截器链 - 这里构建责任链!List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// 如果拦截器链为空,直接反射调用目标方法if (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {// 创建方法调用对象,包含了拦截器链MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// 执行责任链retVal = invocation.proceed();}// 返回结果处理return retVal;}// ... 异常处理和清理代码 ...
}

cglib
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// ... 开头代码省略 ...// 获取目标对象target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);// 获取当前方法的拦截器链 - 责任链构建发生在这里!List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// 如果没有拦截器,直接调用目标方法if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// ... 直接调用目标方法代码 ...}else {// 创建方法调用对象,包含拦截器链MethodInvocation invocation = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);// 执行拦截器链retVal = invocation.proceed();}// ... 返回处理代码 ...return retVal;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {MethodCacheKey cacheKey = new MethodCacheKey(method);// 尝试从缓存获取拦截器链List<Object> cached = this.methodCache.get(cacheKey);if (cached == null) {// 缓存未命中,创建拦截器链cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);// 缓存结果this.methodCache.put(cacheKey, cached);}return cached;
}
小小总结

责任链不是在代理创建时构建的,而是在方法调用时动态构建,只为当前调用的方法构建相关的拦截器链,而不是为所有方法预先构建,通过 methodCache 缓存已构建的拦截器链,避免重复构建,根据方法和目标类在运行时判断哪些 Advisor 适用,形成调用链

Advisor 收集与排序
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {// 创建拦截器列表List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);// 获取目标类Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());// 判断是否存在引介增强boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);// 注册表,用于缓存结果AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();// 遍历所有Advisorfor (Advisor advisor : config.getAdvisors()) {if (advisor instanceof PointcutAdvisor) {// 处理PointcutAdvisor类型的AdvisorPointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {// 将Advisor转换为拦截器MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();boolean match;// 检查方法是否匹配if (mm instanceof IntroductionAwareMethodMatcher) {match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);}else {match = mm.matches(method, actualClass);}if (match) {// 将Advisor转换成拦截器并添加到列表中MethodInterceptor[] interceptors = registry.getInterceptors(advisor);if (mm.isRuntime()) {// 运行时匹配的处理for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {// 直接添加到拦截器链interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {// 处理IntroductionAdvisor// ... existing code ...}else {// 处理其他类型的AdvisorInterceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;
}
责任链执行过程
@Override
@Nullable
public Object proceed() throws Throwable {// 到达链末尾,调用目标方法if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 获取下一个拦截器Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// 动态匹配的拦截器InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// 不匹配,跳过当前拦截器,继续下一个return proceed();}}else {// 执行普通拦截器return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
}

 

AdvisorAdapter 将不同类型的 Advisor 统一适配为 MethodInterceptor 

每个 Advisor 被转换为 MethodInterceptor 后,按顺序组成一个拦截器链,每个拦截器决定是执行自己的逻辑还是传递给下一个拦截器,会通过递增 currentInterceptorIndex 实现链的遍历,递归调用 proceed() 方法,实现责任传递

http://www.dtcms.com/wzjs/143941.html

相关文章:

  • 昌图门户网站保定网站建设方案优化
  • 任何判断网站SEO做的好坏平台推广精准客源
  • 毕业设计做网站怎么样没有限制的国外搜索引擎
  • 课程网站开发卷宗挖掘爱站网
  • 深圳规模较大的网站建设公司私域流量营销
  • 怎么做360网站排名市场推广计划方案模板
  • 网站打开的速度特别慢的原因青岛网站建设优化
  • 域名停靠app大全下载网站入口上海seo推广方法
  • 建筑类企业网站模板seo运营招聘
  • 重庆网站建设选圣矢网络推广需要多少钱
  • 知名b2b网站评论优化
  • 网站举报12321成都搜狗seo
  • 郑州市建设局网站北京seo网站推广
  • laravel 做网站g3云推广靠谱吗
  • 做网站 (公司)长春seo公司哪家好
  • 推广网站广告软件定制开发公司
  • wordpress网页如何公开本地网络seo公司
  • 做外贸上不了国外网站seo外链代发
  • 企业手机网站建设流程2022适合小学生的简短新闻
  • 岳阳做网站 公司电话日本站外推广网站
  • 纺织网站建设百度排行榜小说
  • 广州海珠区最新疫情济南seo排名优化推广
  • 如何制作个人网页文档线上seo关键词优化软件工具
  • qt做网站合肥百度推广排名优化
  • 物流网站建设重要性武汉服装seo整站优化方案
  • 长春建站推荐自己怎么做网站
  • 建设网站的准备工作分为百度指数查询官方网
  • 制作网站源码软件网络整合营销4i原则是指
  • 网站建设相关制度网络营销策划步骤
  • 龙港哪里有做阿里巴巴网站seo外链工具