您的位置:首页 > 编程语言 > Java开发

SpringMVC事务失效的一种情况-bean加载顺序问题

2015-08-15 10:38 573 查看
首先给大家看一个范例java代理的范例:

public class MyInvocationHandler implements InvocationHandler {

// 目标对象,也就是我们主要的业务,主要目的要做什么事
private Object delegate;

/**
* 和你额外需要做得事情,进行绑定,返回一个全新的对象(写法,基本上固定的)
*
* @param delegate
* @return
*/
public Object bind(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(
this.delegate.getClass().getClassLoader(), this.delegate
.getClass().getInterfaces(), this);
}

/**
* 你刚才需要执行的方法,都需要通过该方法进行动态调用
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
// 执行前置的方法
UserDaoSupport.before();
// 通过反射,执行目标方法,也就是你的主要目的
obj = method.invoke(this.delegate, args);
// 执行后置的方法
UserDaoSupport.after();
// 返回值给调用者
return obj;
}

}
public class UserDaoSupport {
public static void before(){
System.out.println("前置日记:打印、启动事务等..");
}

public static void after(){
System.out.println("后置日记:打印、关闭事务等..");
}

public static void other(){
System.out.println("做其他的事..");
}
}

@Test
public void proxyTest() {
UserDao userDao = (UserDao) new MyInvocationHandler().bind(new UserDaoImpl());
userDao.insert();
}
事务其实就是这么回事,对于设置了事务的函数而言,其实就是SpringMVC生成一个代理,访问相应函数,这也就不难解释某种情况事务失效的原因了

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="get*" propagation="REQUIRED" rollback-for="java.lang.Exception" read-only="true"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="interceptorPointCuts"
expression="execution(public * com.leon.web.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="interceptorPointCuts" />
</aop:config>
则com.leon.web.service包下的所有匹配上述三个方法名的函数都会被事务控制,但是现在就出现了一个问题,就是Spring 配置文件加载顺序问题,SpringMVC加载顺序如下:web.xml, *-servlet.xml, applicationContext.xml..... 如果在*-servlet.xml中定义了对applicationContext.xml中bean的ref,自然会往后找,但是如果没有,就正常的加载顺序,如在*-servlet.xml声明了<context:component-scan
base-package="..."/>而你期望这里直接就扫描所有的注解,那么恭喜你,你的事务就无效了,因为,在事务注册到Spring容器之前,你已经初始化了所有的bean,获取该bean就不会通过代理,事务就无从谈起了。因此,合理的配置方式是保证需要事务管理的bean的生成要后于事务的声明,具体方式有很多种,大家可以任意选择
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: