SEO基础

SEO基础

Products

当前位置:首页 > SEO基础 >

如何利用WordPress和抽奖活动在没有网站的情况下进行有效的网络推广?

96SEO 2026-02-19 17:59 0


本篇文章我们看下当一个类里面包含了Transactional注解#xff0c;Spring如…上一篇文章我们介绍了事务开启注解EnableTransactionManagement源码解析《Spring-事务源码解析1》

如何利用WordPress和抽奖活动在没有网站的情况下进行有效的网络推广?

里面提到了2个关键组件这里我们分析下Spring如何利用这2个组件来给Bean创建代理对象。

本篇文章我们看下当一个类里面包含了Transactional注解Spring如何利用上面说的2个组件来实例化Bean如何让这个Bean带有事务功能。

下面三个部分用来介绍

1、Bean如何创建具有事务功能的代理类这里就用到上面2个组件

2、目标方法执行如何被拦截事务拦截

创建Bean当然是看Spring非常经典的doCreateBean方法这里最终就得到目标类的代理对象这中间就包含了Spring如何利用后置处理器控制目标类代理对象创建如何利用切点匹配要添加通知的方法。

因为doCreateBean内容有点多这里我也就贴我认为比较重要的一部分代码。

//假设我们的业务类AService带有Transactional注解,下面通过doCreateBean创建AService的代理对象

protected

{........1、下面一块代码就是通过反射得到AService的实例对象这个还只是通过反射拿到了普通的实例对象不是代理对象。

BeanWrapper

instanceWrapper

this.factoryBeanInstanceCache.remove(beanName);}if

(instanceWrapper

instanceWrapper.getWrappedInstance();................2、把普通实例对象封装ObjectFactory对象存入三级缓存在AOP依赖注入和循环依赖会用到这里我们先忽略。

boolean

(mbd.isSingleton()

isSingletonCurrentlyInCreation(beanName));if

getEarlyBeanReference(beanName,

mbd,

bean));}................3、通过AService普通实例对象生成AService的代理对象也利用了前面提到的2个组件这里的代理对象就包含了事务功能。

逻辑都在初始化Object

exposedObject

instanceWrapper);//属性填充exposedObject

exposedObject,

mbd);//初始化................4、利用三级缓存解决依赖注入和循环依赖这里先忽略。

if

{Object

earlySingletonReference;}}}........return

exposedObject;//返回AService的代理对象

protected

bean;//这里Bean还只是AService的普通实例对象//执行所有后置处理器的Before方法本次忽略wrappedBean

applyBeanPostProcessorsBeforeInitialization(wrappedBean,

beanName);//如果AServcie实现了InitializingBean接口,执行inint方法本次忽略invokeInitMethods(beanName,

wrappedBean,

mbd);//重点执行所有后置处理器的After方法这里会生成AService的代理对象。

wrappedBean

applyBeanPostProcessorsAfterInitialization(wrappedBean,

beanName);return

}Spring里面包含了很多后置处理器那么生成AService代理类的后置处理器也就是我们前面提到的2个组件

1、AutoProxyRegistrar组件会往Spring容器中注册InfrastructureAdvisorAutoProxyCreator后置处理器

2、ProxyTransactionManagementConfiguration组件会往Spring容器中注册切面进去

在执行到InfrastructureAdvisorAutoProxyCreator后置处理器的After方法里面主要是为通过调用wrapIfNecessary方法来创建AService代理对象。

Override

postProcessAfterInitialization(Nullable

Object

{//根据Bean的信息来获取AService所有的AdvisorAdvisor可以近似的把他理解成切面当然Advisor和切面不是一个东西为了方便理解就近似把他看做是切面。

//这里拿到的切面是符合AService的切面就Spring会有很多事务相关的切面每个切面有自己定义的切点规则比如有的切面处理X注解的,有的切面只处理Transactional//这里只返回AService符合切点规则的那个切面。

为什么要拿切面因为Spring在创建代理类的时候就是要基于切面里面的通知来对目标方法进行拦截。

Object[]

specificInterceptors

getAdvicesAndAdvisorsForBean(bean.getClass(),

beanName,

{//利用Advices来生成AService的代理对象。

Object

proxy

SingletonTargetSource(bean));return

proxy;}return

getAdvicesAndAdvisorsForBean是如何获取符合规则的Advisor

//获取切面

getAdvicesAndAdvisorsForBean(Class?

beanClass,

findEligibleAdvisors(beanClass,

beanName);//获取切面if

findCandidateAdvisors();//2、过滤出AService符合切点规则ListAdvisor

eligibleAdvisors

findAdvisorsThatCanApply(candidateAdvisors,

beanClass,

}上面包含2块内容第一块是获取所有切面第二块是过滤出符合规则的切面下面我们分别看下如何获取所有切面。

//获取所有的Advisor这里的Advisor就包含了我们前面提到的组件ProxyTransactionManagementConfiguration

//ProxyTransactionManagementConfiguration会往Spring容器里面注册3个Bean。

//其中切面BeanFactoryTransactionAttributeSourceAdvisor,

ListAdvisor

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory,

Advisor.class,

false);this.cachedAdvisorBeanNames

advisors

{........advisors.add(this.beanFactory.getBean(name,

Advisor.class));//通过Name获取Advisor对应的Bean这里就是BeanFactoryTransactionAttributeSourceAdvisor........}return

advisors;

//从Advisor集合中挑选出beanClass符合的Advisor

protected

findAdvisorsThatCanApply(ListAdvisor

candidateAdvisors,

AopUtils.findAdvisorsThatCanApply(candidateAdvisors,

beanClass);

findAdvisorsThatCanApply(ListAdvisor

candidateAdvisors,

ArrayList();//定义符合规则的Advisor集合同以最终返回。

//引介切面过滤for

(Advisor

{//如果Advisor是引介切面并且符合规则引介切面是基于类层面判断是否符合规则if

(candidate

{eligibleAdvisors.add(candidate);}}//切点切面过滤boolean

hasIntroductions

!eligibleAdvisors.isEmpty();for

(Advisor

{continue;}//进到这里说明这个Advisor是切点切面切面切面是基于方法层面判断是否符合规则。

if

(canApply(candidate,

{eligibleAdvisors.add(candidate);}}return

eligibleAdvisors;

advisor).getClassFilter().matches(targetClass);}

else

//通过方法层面判断其实就是判断方法是否有Transactional注解当然每个切点的实现不一样判断逻辑也会有差异

public

(!Proxy.isProxyClass(targetClass))

{classes.add(ClassUtils.getUserClass(targetClass));}classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));//拿到目标类for

(Class?

ReflectionUtils.getAllDeclaredMethods(clazz);for

(Method

{//判断方法是否匹配这里其实通过切点类判断是否方法是否包含特定注解。

比如Transactionalif

targetClass))

这一段我们讲了如何利用getAdvicesAndAdvisorsForBean拿到目标类的advisor因为Spring在整个启动过程中会存在很多advisor不是所有的advisor都能给AService来用我们需要通过切面中的切点规则来判断是否符合规则。

1.2

再回到wrapIfNecessary方法的第二块内容生成代理对象。

protected

getAdvicesAndAdvisorsForBean(bean.getClass(),

beanName,

{//2、结合advisor生成AService的代理对象。

Object

proxy

SingletonTargetSource(bean));return

proxy;}return

{//创建ProxyFactory用来生成代理对象ProxyFactory

proxyFactory

ProxyFactory();proxyFactory.copyFrom(this);//拿到切面添加进去Advisor[]

advisors

specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);proxyFactory.setFrozen(this.freezeProxy);...省略部分代理return

proxyFactory.getProxy(getProxyClassLoader());

}上面最终调用getProxy方法来生成代理对象那么JDK和Cglib都实现了getProxy方法这里我们分别看下他们如何创建对象。

1.2.1

AopProxyUtils.completeProxiedInterfaces(this.advised,

true);...省略部分代理//这里的this是JdkDynamicAopProxy//生成代理对象代理对象需要实现proxiedInterfaces集合所有接口//当目标对象被调用的时候会先进到JdkDynamicAopProxy的invoke方法里面return

Proxy.newProxyInstance(classLoader,

proxiedInterfaces,

this.advised.getTargetClass();Class?

proxySuperClass

(rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR))

{proxySuperClass

rootClass.getSuperclass();Class?[]

additionalInterfaces

{this.advised.addInterface(additionalInterface);}}Enhancer

enhancer

createEnhancer();enhancer.setSuperclass(proxySuperClass);

//代理类的父类也就是目标类AServcieenhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

//代理类需要实现的接口enhancer.setStrategy(new

ClassLoaderAwareGeneratorStrategy(classLoader));//添加回调方法这些回调类都实现了MethodInterceptor接口当AService的方法被调用时会进到MethodInterceptor里面的intercept方法里面去Callback[]

callbacks

getCallbacks(rootClass);Class?[]

types

Class?[callbacks.length];enhancer.setCallbackFilter(new

ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(),

this.fixedInterceptorOffset));。

省略部分代码return

createProxyClassAndInstance(enhancer,

callbacks);

}getCallbacks会拿到很多MethodInterceptor的实现类作为回调添加到代理类里面去当AService有方法被调用时就会进被MethodInterceptor的intercept方法拦截在intercept里面调用切面里面的通知方法。

这里MethodInterceptor的实现类就包含DynamicAdvisedInterceptor。

1.2小结

通过JDK和Cglib创建代理类并添加拦截方法在AService方法被执行时被invoke方法或者intercept方法拦截。

三、目标方法执行如何被拦截事务拦截

上面我们介绍了如何创建代理对象并且在创建代理对象时拦截目标方法这里我们看下当目标方法被执行在拦截里面做了什么操作。

当目标方法被调用时会被JdkDynamicAopProxy的invoke方法拦截或者是MethodInterceptor的intercept方法拦截在invoke和intercept里面会通过切面拿到通知在挨个的执行通知最后在执行目标方法

Override

{//获取符合目标方法的拦截器MethodInterceptor集合ListObject

chain

this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,

targetClass);if

AopProxyUtils.adaptArgumentsIfNecessary(method,

args);retVal

AopUtils.invokeJoinpointUsingReflection(target,

method,

argsToUse);//如果拦截器集合为空就直接调用目标方法}

else

ReflectiveMethodInvocation(proxy,

target,

targetSource.getTarget();Class?

targetClass

null);//1、获取符合目标方法的拦截器MethodInterceptor集合。

这里是拿切里的通知通知是MethodInterceptor类型ListObject

chain

this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,

targetClass);Object

Modifier.isPublic(method.getModifiers()))

{retVal

argsToUse);//如果拦截器集合为空就直接调用目标方法}

else

{//2、生成拦截器链使用的是责任链设计模式。

在挨个调用拦截器。

最后调用目标方法retVal

new

}关于获取拦截器集合和调用拦截器链可以看到我的这篇文章《代理生成拦截器和调用拦截器》

3、触发事务拦截器

然后执行拦截器链中的最开始的拦截器后面一次遍历但是此时的拦截器就只有一个就是TransactionInterceptor事务方法拦截器

进到TransactionInterceptor就会执行TransactionInterceptor的invoke方法,下面看下invoke的流程

1、先拿到事务管理器的事务类型PROPAGATION_REQUIRED,ISOLATION_DEFAULT;

2、在拿到事务的管理器也就是DataSourceTransactionManager

Override

AopUtils.getTargetClass(invocation.getThis())

invokeWithinTransaction(invocation.getMethod(),

targetClass,

getTransactionAttributeSource().getTransactionAttribute(method,

targetClass);//2、事务管理器DataSourceTransactionManagerfinal

determineTransactionManager(txAttr);//生成事务txInfo里面包含本次事务状态隔离级别事务处理器当本次事务执行完后需要关闭本次事务TransactionInfo

txInfo

createTransactionIfNecessary(tm,

txAttr,

invocation.proceedWithInvocation();}catch

(Throwable

{//更改txInfo里面的状态completeTransactionAfterThrowing(txInfo,

ex);throw

{cleanupTransactionInfo(txInfo);}commitTransactionAfterReturning(txInfo);//根据状态是否commitreturn

retVal;

1、前面我们在Bean的实例化时用到了第一个组件InfrastructureAdvisorAutoProxyCreator用来触发wrapIfNecessary方法。

2、在wrapIfNecessary方法里面我们利用了第二个组件ProxyTransactionManagementConfiguration生成的切面BeanFactoryTransactionAttributeSourceAdvisor通过BeanFactoryTransactionAttributeSourceAdvisor的切点AnnotationTransactionAttributeSource来判断AService是否符合切点规则也就是解读AService类的方法是否包含Transactional注解。

五、疑问

1、带有Transaction注解的Bean实例化的时候怎么如果判断该Bean带有Transaction方法

1、InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization

—2、BeanFactoryTransactionAttributeSourceAdvisor

—3、AnnotationTransactionAttributeSource

—4、SpringTransactionAnnotationParser判断Transaction

最终通过SpringTransactionAnnotationParser来判断Bean的方法是否带有Transaction注解

InfrastructureAdvisorAutoProxyCreator里面有个advisedBeans属性在Bean的创建过程会判断Bean里面

是否是带有事务注解Transaction的方法如果有就会被加到advisedBeans里面去。

private

1、BeanFactoryTransactionAttributeSourceAdvisor事务增强器在advisedBeans是false的形式存在

2、transactionInterceptor也是false

2、带有Transaction注解的代理Bean在哪个流程被创建

在执行BeanPostProcess处理器链的时候由InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization方法执行创建该方法会调用wrapIfNecessary方法完成代理创建

protected

{.......//这里是拿到BeanFactoryTransactionAttributeSourceAdvisor也就是“事务增强器”Object[]

specificInterceptors

getAdvicesAndAdvisorsForBean(bean.getClass(),

beanName,

{this.advisedBeans.put(cacheKey,

Boolean.TRUE);//key就是带有Transaction的BeanNameObject

proxy

SingletonTargetSource(bean));return

bean;

proxyFactory.setTargetSource(目标对象LLServcieImpl);

proxyFactory.setInterfaces(目标接口LLServcie);

proxyFactory.addAdvisor(事务增强器BeanFactoryTransactionAttributeSourceAdvisor);

proxyFactory.getProxy(getProxyClassLoader())//调用下面的代码//2、生成动态代理对象

proxiedInterfacesAopProxyUtils.completeProxiedInterfaces(事务增强器,

true);

//设置代理对象要实现接口和InvocationHandler对象

Proxy.newProxyInstance(classLoader,

proxiedInterfaces,

JdkDynamicAopProxy类);其中proxiedInterfaces包含接口

{Class3511}

cn.tedu.sample2.util.LLServcie”

{Class3676}

org.springframework.aop.SpringProxy”

{Class5780}

org.springframework.aop.framework.Advised”

{Class3897}

org.springframework.core.DecoratingProxy”

4、InfrastructureAdvisorAutoProxyCreator类的作用

1、postProcessBeforeInstantiation方法主要是针对所有要创建的Bean,判断存到advisedBeans里面是false还是true

2、postProcessAfterInitialization方法处理带有Transcation的Bean创建代理Bean

六、总结

1、先通过EnableTransactionManagement引入TransactionManagementConfigurationSelector

2、通过TransactionManagementConfigurationSelector导入AutoProxyRegistrarProxyTransactionManagementConfiguration

3、AutoProxyRegistrar会向容器中注册InfrastructureAdvisorAutoProxyCreator

4、ProxyTransactionManagementConfiguration会向容器定义三个Bean事务增强器、Transaction注解解析器、事务方法拦截器

5、执行Bean的后置处理器时通过InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization方法创建代理对象

6、创建代理对象时通过事务增强器BeanFactoryTransactionAttributeSourceAdvisor来得到代理类要实现的接口SpringProxy、Advised、DecoratingProxy最终生成代理对象

7、当请求进来时先进入JdkDynamicAopProxy的invoke方法

8、invoke里面会调用TransactionInterceptor的invoke方法里面会调用invokeWithinTransaction方法

9、invokeWithinTransaction里面会在调用目标方法前开启事务catch失败设置状态然后finally根据状态来确认是否commit



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback