在代理模式(默认设置)下,只拦截通过代理进入的外部方法调用。这意味着实际上,自调用目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Transactional标记,也不会在运行时导致实际的事务。
所以我想使用AspectJ,但我无法通过sessionFactory.getCurrentSession()
获取会话,这会导致以下异常。
org.hibernate.HibernateException:没有Hibernate会话绑定到线程,配置不允许在这里创建非事务性的
我在运行时添加了VM参数。 -javaagent:/Users/xx/workStation/workspace/SpringHibernate/src/lib/spring-instrument-3.2.8.RELEASE.jar
这是配置文件 aop.xml文件
<aspectj>
<weaver options="-Xset:weaveJavaxPackages=true -showWeaveInfo">
</weaver>
beans.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref = "dataSource"/>
<property name="mappingResources">
<list>
<value>config/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=false
</value>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref = "sessionFactory"/>
<property name="nestedTransactionAllowed" value = "true"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="txManager" />
<context:load-time-weaver />
感谢您的回答。
如果我删除了aop.xml,我收到了一个警告:
warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
。
否则我得到了以下信息
[AppClassLoader@546b97fd] weaveinfo Join point 'method-execution(java.util.List com.yonghui.sh.service.impl.UserServiceBean.getUsers())' in Type 'com.yonghui.sh.service.impl.UserServiceBean' (UserServiceBean.java:106) advised by around advice from 'org.springframework.transaction.aspectj.AnnotationTransactionAspect' (AbstractTransactionAspect.aj:59)
[AppClassLoader@546b97fd] weaveinfo Join point 'method-execution(void com.yonghui.sh.service.txtest.TxTestB.txC())' in Type 'com.yonghui.sh.service.txtest.TxTestB' (TxTestB.java:32) advised by around advice from 'org.springframework.transaction.aspectj.AnnotationTransactionAspect' (AbstractTransactionAspect.aj:59)
。
我认为课程是编织的。我只是使用JUnit来运行一些不在Web上下文中的测试。
似乎问题是“静态的”。
static UserService userService;
static TxTest txTest;
static TxTestX txTestx;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
userService = (UserService)ac.getBean("UserService");
txTest = (TxTest)ac.getBean("txTestA");
txTestx = (TxTestX)ac.getBean("txTestX");
}
如果我不使用JUnit,它运作良好。
public class TxTestMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
TxTest txTestA = (TxTest)ac.getBean("txTestA");
txTestA.txA();
}
}
怎么回事?
答案 0 :(得分:0)
在代理模式(默认设置)下,只有外部方法调用 通过代理进入是截获的。这意味着 自调用,实际上是目标对象调用中的一个方法 目标对象的另一种方法,不会导致实际的 即使调用的方法被标记,运行时的事务也是如此 @Transactional。
我不知道这里是否存在问题但是bean可以通过代理调用自己的方法。只需在您的bean接口(如ApplicationContextAware和BeanNameAware)中实现,并使用这两个,您可以询问有关您实际所在的bean的上下文,并通过代理(在事务中)调用任何方法。这当然只有当范围是SINGLETON时才有效,如果是PROTOTYPE,还有一些方法可以通过API实现。