我在班上使用@Aspect注释定义了一个切入点。
我使用我在上下文中定义的自定义注释来配置切入点:
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- Messaging pointcut -->
<bean id="messagePointcut" class="com.adobe.codex.aspects.MessagePointcut" >
<constructor-arg ref="msgPointcutEntityFactory"/>
<property name="buildDao" ref="buildDao"/>
</bean>
<!-- enable our own annotation -->
<aop:config proxy-target-class="true">
<aop:aspect ref="messagePointcut">
<aop:pointcut id="proxiedMethods" expression="@annotation(com..codex.aspects.annotation.MessageGateway)"/>
<aop:around pointcut-ref="proxiedMethods" method="interceptAnnotatedMethod"/>
</aop:aspect>
</aop:config>
不幸的是,如果我在切入点中引用了buildDao,buildDao中的entityManager总是为null。
不确定解决此问题的最佳方法是什么。
我假设问题是所使用的编织(加载时间)不知道如何从entityManagerFactory bean创建一个entityManager。
这是我的dao上下文的片段。
<context:annotation-config />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<util:properties
location="classpath:com//codex/dao/jpa/hibernate.properties" />
</property>
</bean>
<bean id="buildDao" class="com..codex.dao.jpa.JpaBuildDao">
<description>
A DAO for Builds.
</description>
<property name="queryHelper" ref="queryHelper" />
<property name="partDao" ref="partDao" />
<property name="buildQueryFactory" ref="buildQueryFactory" />
</bean>
这是我的切入点:
@Aspect @Transactional() 公共类MessagePointcut实现Ordered,MsgObservable {
private MsgPointcutEntityFactory msgEntityFactory;
private BuildDao buildDao;
public void setBuildDao(BuildDao buildDao) {
this.buildDao = buildDao;
}
public MessagePointcut(MsgPointcutEntityFactory msgEntityFactory){
this.msgEntityFactory = msgEntityFactory;
}
@Transactional(readOnly = true)
public Object interceptAnnotatedMethod(ProceedingJoinPoint pjp) {
Object returnedEntity = null;
Object originalEntity = null;
try { //
// do stuff before executing the call
originalEntity = msgEntityFactory.fetch(id, Build.class);
//execute the call
returnedEntity = pjp.proceed();
// do stuff after executing the call
// ...
} catch (Throwable e) {
e.printStackTrace();
}
return returnedEntity;
}
@Override
public int getOrder() {
return 2;
}
}
还有我的dao片段
@Repository 公共类JpaBuildDao实现了BuildDao {
private static final Log log = LogFactory.getLog(JpaBuildDao.class);
@PersistenceContext
private EntityManager entityManager;
private QueryHelper queryHelper;
private BuildQueryFactory standardQueryFactory;
private PartDao partDao;
public Build getFlatBuild(Integer id) {
Build returnBuild;
Query query = entityManager.createQuery(
"SELECT b FROM Build b " +
"WHERE " +
"b.id = :id");
query.setParameter("id", id);
returnBuild = (Build) query.getSingleResult();
return returnBuild;
}
答案 0 :(得分:1)
取得了一些进展。真正的问题是buildDao被原始注入切入点,没有实例化entityManager所需的Jpa代理。
事实证明只有在另一个配置细节进入混合时才会出现问题。我还有两个将bean注入我的切入点的MethodInvokingFactoryBean实例:
<bean id="registerListenerJms"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref local="messagePointcut" />
</property>
<property name="targetMethod">
<value>registerObserver</value>
</property>
<property name="arguments">
<list>
<ref bean="jmsGateway" />
</list>
</property>
</bean>
<bean id="registerListenerAmf"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref local="messagePointcut" />
</property>
<property name="targetMethod">
<value>registerObserver</value>
</property>
<property name="arguments">
<list>
<ref bean="amfGateway" />
</list>
</property>
</bean>
当我删除这两个bean时,我的切入点没有获得原始代理,但是它获得了一个带有dao引用的JdkDynamicAopProxy。
不知道为什么MethodInvokingFactoryBean会混淆注入dao,但确实如此。
底线是暂时我正在删除实现我的观察者模式的MethodInvokingFactoryBean,并且在要挂钩的bean上使用切入点的依赖项。
不是一个完整的解决方案,而是一个可接受的解决方法。