//这个方法不加事务注解
@Override
public void testA() {
insertSelective2(null);
}
//这个加了注解
@Transactional
@Override
public int insertSelective2(Org record2) {
System.out.println("当前的class"+this.getClass());
Org record = new Org();
record.setParentId(0l);
record.setOrgName("测试");
record.setHasChild(false);
if(record.getCreateTime() == null){
record.setCreateTime(new Date());
}
if(record.getUpdateTime() == null){
record.setUpdateTime(new Date());
}
orgMapper.insertSelective(record);
int a = 1/0;
return 0;
}
测试类
@Test
public void test1(){
System.out.println("类"+orgService.getClass());
orgService.testA();
}
输出结果:
类class com.sun.proxy.$Proxy105
当前的classclass com.glodio.service.impl.OrgServiceImpl
如果有@Transactional类,spring会帮我们生成代理类,如果执行的方法有注解需要处理的,spring会帮我们处理,testA()中调用insertSelective2()是this.insertSelective2() 当前打出类的OrgServiceImpl 所以调用的是OrgServiceImpl 类的insertSelective2方法。
源码:
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
.....
//得到方法的拦截器链,
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
//如果是空进执行
if (chain.isEmpty()) {
//处理方法参数的
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//调用反射代码
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
ReflectionUtils.makeAccessible(method);
//调用处理方法
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}