当方法签名包含Object ... args时,如何使用动态代理与JSF

时间:2011-02-08 02:31:58

标签: spring jsf jpa aspectj dynamic-proxy

我在使用初始化为Spring Beans的Spring,JPA和动态代理DAO类时遇到了一些麻烦。这个特别的项目在持久性/交易方面一直困扰着我,并且我希望能够一劳永逸地把它钉在一起。

首先,这是来自DAO界面的方法:

/**
 * Perform a named query using numbered parameters and return the results as a list
 * @param name
 * @param params
 * @return query results
 */
List getNQasList(String name, Object... params);

使用postProcessBeanFactory方法自动向Spring注册此bean:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

    this.beanFactory = beanFactory;
    for (Class entityClass : this.getPersistedClassList()) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        ConstructorArgumentValues constructorVals = new ConstructorArgumentValues();
        constructorVals.addIndexedArgumentValue(0, entityClass);
        beanDefinition.setConstructorArgumentValues(constructorVals);
        beanDefinition.setBeanClass(GenericDAOImpl.class);
        beanDefinition.setAutowireCandidate(true);
        beanDefinition.setLazyInit(true);
        beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
        String simpleName = entityClass.getSimpleName();
        String convertedName = "" + simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1) + "Dao";
        registry.registerBeanDefinition(convertedName, beanDefinition);
    }
}

方法getPersistedClassList()读取persistence.xml并查找所有JPA类。上面的方法用Spring注册每个实例,因此可以通过变量“entityNameDao”轻松访问它们。因为这个类是一个事务类,所以它被初始化为动态Java代理,这就是我的问题开始的地方。 JSF不再通过其接口感知对象,而是直接查看代理,实际上将上述方法定义显示为:

List getNQasList(String name, Object[] params);

这使得从JSF访问比使用Object ... params签名方法更加困难。有没有什么方法可以让JSF通过它们的接口识别这些对象,或者说服Spring以某种方式不动态代理它们?或者,如何在EL中执行以下操作,如果我尝试,它会给出关于花括号的错误:

new Object[] {...}

我的春季配置与持久性相关,包括交易建议,包含在下面,以便进行衡量。

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="${JDBC_CONNECTION_STRING}?autoReconnect=true&amp;useUnicode=true&amp;connectionCollation=utf8_general_ci&amp;characterSetResults=utf8"/>
    <property name="username" value="${PARAM1}"/>
    <property name="password" value="${PARAM2}"/>
    <property name="validationQuery" value="select 1"/>
</bean>

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<context:annotation-config/>

<!-- Enable aspectj based transactions -->
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true"/>
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution
  of an operation defined by the GenericDAOImpl class -->
<aop:config>
    <aop:pointcut id="DaoOps" expression="execution(* daos.GenericDAOImpl.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="DaoOps"/>
</aop:config>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
            <property name="showSql" value="true"/>
        </bean>
    </property>
</bean>

0 个答案:

没有答案