1

我在课堂上使用@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 始终为空。

不确定解决此问题的最佳方法是什么。

我假设问题是使用的编织(加载时间)不知道如何从 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;
}

}

和我的道的片段

@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;
}
4

1 回答 1

1

取得了一些进展。真正的问题是 buildDao 被原始注入到没有实例化 entityManager 所需的 Jpa 代理的切入点中。

事实证明,这个问题只有在另一个配置细节出现时才会出现。我还有两个 MethodInvokingFactoryBean 实例将 bean 注入我的切入点:

<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 时,我的切入点没有获得原始代理,但它获得了一个 JdkDynamicAopProxy 与对 dao 的引用。

不知道为什么 MethodInvokingFactoryBean 会搞砸注入 dao,但确实如此。

底线是目前我正在删除实现我的观察者模式的 MethodInvokingFactoryBean 并依赖于切入点对想要挂钩的 bean 的依赖。

不是一个完整的解决方案,而是一个可接受的解决方法。

于 2011-03-23T19:56:14.963 回答