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

cdn如何做网站统计上海旧房翻新装修哪家好

cdn如何做网站统计,上海旧房翻新装修哪家好,网站建设学习要多久,4在线做网站在Spring中,Transactional注解的处理涉及到多个关键组件,包括Advisor、Target、ProxyFactory等。下面是详细的解析和代码示例,解释这些组件是如何协同工作的。 1. 关键组件介绍 1.1 Advisor Advisor是一个Spring AOP的概念,它包…

在Spring中,@Transactional注解的处理涉及到多个关键组件,包括AdvisorTargetProxyFactory等。下面是详细的解析和代码示例,解释这些组件是如何协同工作的。

1. 关键组件介绍

1.1 Advisor

Advisor是一个Spring AOP的概念,它包含了切点(Pointcut)和通知(Advice)。在事务管理中,TransactionAttributeSourceAdvisor是一个典型的Advisor。

1.2 Target

Target是指被代理的目标对象,即实际执行业务逻辑的对象。

1.3 ProxyFactory

ProxyFactory是Spring提供的用于创建代理对象的工厂类。它可以使用JDK动态代理或CGLIB创建代理对象。

2. @Transactional的处理流程

  1. 解析注解:Spring扫描@Transactional注解。
  2. 创建Advisor:创建包含事务处理逻辑的Advisor
  3. 创建代理对象:使用ProxyFactory为目标对象创建代理对象,并将Advisor加入到代理对象中。

3. 代码示例

3.1 配置类

首先,通过@EnableTransactionManagement启用事务管理。

import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement
public class AppConfig {// DataSource, EntityManagerFactory, TransactionManager beans configuration
}
3.2 目标对象和接口

定义一个业务接口和其实现类:

public interface MyService {void myTransactionalMethod();
}@Service
public class MyServiceImpl implements MyService {@Override@Transactionalpublic void myTransactionalMethod() {// 业务逻辑System.out.println("Executing myTransactionalMethod");}
}
3.3 ProxyFactory和Advisor

使用ProxyFactoryTransactionAttributeSourceAdvisor来创建代理对象并处理事务:

import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;public class ProxyFactoryExample {public static void main(String[] args) {// 创建目标对象MyService target = new MyServiceImpl();// 创建事务属性源TransactionAttributeSource transactionAttributeSource = new NameMatchTransactionAttributeSource();// 创建事务拦截器TransactionInterceptor transactionInterceptor = new TransactionInterceptor();transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);// 创建AdvisorDefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();advisor.setAdvice(transactionInterceptor);// 创建ProxyFactoryProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(target);proxyFactory.addAdvisor(advisor);// 创建代理对象MyService proxy = (MyService) proxyFactory.getProxy();// 调用代理对象的方法proxy.myTransactionalMethod();}
}

4. 详细解释

4.1 创建目标对象
MyService target = new MyServiceImpl();

这是被代理的目标对象,它包含了业务逻辑,并使用了@Transactional注解。

4.2 创建事务属性源
TransactionAttributeSource transactionAttributeSource = new NameMatchTransactionAttributeSource();

TransactionAttributeSource用于解析事务属性。NameMatchTransactionAttributeSource是一个实现类,可以基于方法名称匹配事务属性。

4.3 创建事务拦截器
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);

TransactionInterceptor实现了MethodInterceptor接口,用于在方法调用前后处理事务逻辑。

4.4 创建Advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setAdvice(transactionInterceptor);

DefaultPointcutAdvisor包含了事务拦截器,可以在匹配的方法上应用事务逻辑。

4.5 创建ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(advisor);

ProxyFactory用于创建代理对象。它将目标对象和Advisor结合起来,生成代理对象。

4.6 创建代理对象并调用方法
MyService proxy = (MyService) proxyFactory.getProxy();
proxy.myTransactionalMethod();

通过ProxyFactory.getProxy()方法创建代理对象,并调用代理对象的方法。这时,事务拦截器会在方法调用前后执行事务处理逻辑。

5. 总结

通过以上代码示例,可以看出Spring如何解析@Transactional注解,并使用AdvisorTargetProxyFactory创建代理对象来处理事务逻辑。这些组件协同工作,实现了自动的事务管理。

proxyFactory源码

targetSource与代理对象是两个对象,
在调用代理对象的时候,实际上是要被DynamicAdvisedInterceptor拦截,之后在拦截方法中执行执行拦截器调用链,并把targetSource传给拦截器。
相当于把targetSource对象(非类)作为成员变量传递给代理对象,然后对targetSource对象的方法调用增强。
类->BeanDefinition->bean初始化->为bean添加后置处理器,替换bean对象为proxy对象,其中bean对象作为代理对象的成员变量targetSource,代理对象通过在拦截方法中对targetSource对象的方法调用前后执行advisor的方法。

对比 @Configuration对@bean方法的处理,是直接生成子类,子类重写@bean方法,子类作为BeanDefinition替换原始@Configuration注解的类, 因此在子类中的this调用就是对子类重写的方法调用。

//CglibAopProxy
/*** General purpose AOP callback. Used when the target is dynamic or when the* proxy is not frozen.*/private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {private final AdvisedSupport advised;public DynamicAdvisedInterceptor(AdvisedSupport advised) {this.advised = advised;}@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;Object target = null;TargetSource targetSource = this.advised.getTargetSource();try {if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = invokeMethod(target, method, argsToUse, methodProxy);}else {// We need to create a method invocation...// 链式调用retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal = processReturnType(proxy, target, method, retVal);return retVal;}finally {if (target != null && !targetSource.isStatic()) {targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}}@Overridepublic boolean equals(@Nullable Object other) {return (this == other ||(other instanceof DynamicAdvisedInterceptor &&this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));}/*** CGLIB uses this to drive proxy creation.*/@Overridepublic int hashCode() {return this.advised.hashCode();}}
//ReflectiveMethodInvocation
@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.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 {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.//调用 @Transactional事务拦截器return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}
//TransactionInterceptor@Nullablepublic Object invoke(MethodInvocation invocation) throws Throwable {Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {@Nullablepublic Object proceedWithInvocation() throws Throwable {// 拦截器链式调用return invocation.proceed();}public Object getTarget() {return invocation.getThis();}public Object[] getArguments() {return invocation.getArguments();}});}

拦截器链式调用

http://www.15wanjia.com/news/159619.html

相关文章:

  • 医院网站开发公司华梦服饰网站建设中
  • 网站栏目一般有哪些建设网站的网址
  • 网站有什么用做电商的几个网站吗
  • 阿里云做电影网站西安seo服务培训
  • wp企业网站模板莆田市网站建设
  • 制作网站软件排行榜专业餐饮vi设计公司
  • php网站后台制作教程温州网页模板建站
  • 网站数据库怎么做同步吗直播网站排名
  • 茂名模板建站代理网站建设公司浩森宇特
  • 贵州贵阳建网站的电话这几年做那个网站能致富
  • 加强信息管理 维护网站建设建网站需要钱吗
  • 多多返利网站建设程序广州微网站建设服务
  • 电商网站后台功能公司网站域名备案流程
  • 做平面设计应该在哪个网站求职常州经开区建设局网站
  • 新网站如何做推广软文开发一个电商app软件多少钱
  • p2p网站建设要点企业seo案例
  • 网站空间后台登录公司做营销型网站
  • 管理外贸网站模板做网站建设公司哪家好?
  • 青岛做网站找哪家好济南推广公司有哪些
  • 企业设计网站公司排名建设银行租房平台网站6
  • 个人电脑做外网网站网络推广培训哪个好
  • 兴义市住房城乡建设局网站外贸网站优化排名
  • 什么是新闻源网站一级域名二级域名哪个好
  • 企业官网网站建设手机端网站开发视频
  • 做设计灵感的网站建设网站需要两种服务支持
  • html5技术可以制作网站吗建设网站总经理讲话范本
  • 东莞网站优化一般多少钱百度app官网下载
  • 湖北省随州市建设厅网站旅游网页设计说明200字
  • 长沙门户网站建设seo站群系统
  • 中国交通建设工程监督管理局网站织梦建站系统教程