Pergunta

Eu tenho dois proxies de primavera configurados:

  <bean id="simpleBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref local="simpleBeanTarget"/>
    </property>
    <property name="interceptorNames">
        <list>
            <value>cacheInterceptor</value>
        </list>
    </property>
</bean>   



 <bean id="springDao" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="springDaoTarget"/>
        <property name="interceptorNames">
            <list>
                <value>daoInterceptor</value>
            </list>
        </property>

    </bean>

Simplebean funciona muito bem - Springdao não.

A aula de Springdao parece:

public class SpringDao extends JdbcDaoSupport {

private SimpleJdbcTemplate simpleJdbcTemplate;

public SimpleJdbcTemplate getSimpleJdbcTemplate() {

    if (simpleJdbcTemplate==null) {
        simpleJdbcTemplate= new SimpleJdbcTemplate(getDataSource());
    }
    return simpleJdbcTemplate;
}
    ...

E eu tenho meu teste de unidade de forma automática assim:

@Autowired
@Qualifier("springDao")
protected SpringDao springDao;

E a primeira indicação que algo está errado é eu recebo este erro:

Não foi possível o campo automático :. . . Exceção aninhada é java.lang.illegalargumentException

Se eu comentar a anotação @qualifier e executar meu teste de unidade novamente, entendo isso:

Nenhum feijão exclusivo do tipo ... feijão único esperado, mas encontrado 2: [Springdaotarget, Springdao

Isso é o que eu esperava.

Então eu mudei minha conduta automática para

@Autowired
@Qualifier("springDaoTarget")
protected SpringCustomerCapacityDao springDao;

E adicionou o seguinte ao meu teste de unidade:

        Object proxy = applicationContext.getBean("springDao");

    Assert.assertNotNull(proxy);
    Assert.assertTrue(proxy instanceof SpringDao);

E a instância do teste falhou, que (para mim) significa que meu proxy não é realmente o meu proxy.

Então, estou confuso. O que está acontecendo? Como posso consertar isso?

Editar Aqui está a definição solicitada de Springdatarget, que decepcionará muitas pessoas:

<bean id="springDaoTarget" class="com.company.SpringDao">

Foi útil?

Solução

Se o alvo do seu proxy implementar pelo menos uma interface, o comportamento padrão da Spring será criar um proxy JDK que implementa todas as interfaces do destino. Isso significa que não será uma subclasse da classe de destino. Você pode substituir isso forçando a criação de proxies CGLIB, que são subclasses dinâmicas do destino.

Como regra geral, se você vai usar a AOP, mas use apenas interfaces de maneira limitada, você deseja forçar o CGLIB. Caso contrário, você terá muitos proxies JDK em seu contêiner, que não são do mesmo tipo que as implementações de feijão que você carregou.

Veja Cliff Meyers Blog: Spring AOP: CGLIB ou JDK Proxies dinâmicos?

Outras dicas

Foi fácil de corrigir, uma vez que eu descobri. Springdao não herda mais do JDBCDAOSUPPORT e agora funciona.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top