cdn如何做网站统计,网站的目的及功能规划,wordpress超时退出,阜阳做网站在Spring中#xff0c;Transactional注解的处理涉及到多个关键组件#xff0c;包括Advisor、Target、ProxyFactory等。下面是详细的解析和代码示例#xff0c;解释这些组件是如何协同工作的。
1. 关键组件介绍
1.1 Advisor
Advisor是一个Spring AOP的概念#xff0c;它包…在Spring中Transactional注解的处理涉及到多个关键组件包括Advisor、Target、ProxyFactory等。下面是详细的解析和代码示例解释这些组件是如何协同工作的。
1. 关键组件介绍
1.1 Advisor
Advisor是一个Spring AOP的概念它包含了切点Pointcut和通知Advice。在事务管理中TransactionAttributeSourceAdvisor是一个典型的Advisor。
1.2 Target
Target是指被代理的目标对象即实际执行业务逻辑的对象。
1.3 ProxyFactory
ProxyFactory是Spring提供的用于创建代理对象的工厂类。它可以使用JDK动态代理或CGLIB创建代理对象。
2. Transactional的处理流程
解析注解Spring扫描Transactional注解。创建Advisor创建包含事务处理逻辑的Advisor。创建代理对象使用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 {OverrideTransactionalpublic void myTransactionalMethod() {// 业务逻辑System.out.println(Executing myTransactionalMethod);}
}3.3 ProxyFactory和Advisor
使用ProxyFactory和TransactionAttributeSourceAdvisor来创建代理对象并处理事务
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注解并使用Advisor、Target和ProxyFactory创建代理对象来处理事务逻辑。这些组件协同工作实现了自动的事务管理。
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;}OverrideNullablepublic 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);ListObject 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
OverrideNullablepublic 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 {// Its 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);}}//TransactionInterceptorNullablepublic 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();}});}