Pergunta

Utilizando Weld 1.1.13.Final em teste com Arquillian....

Digamos que eu injete algo volátil em um campo.Algo como uma propriedade sujeita a alterações que desejo que o bean proprietário do ponto de injeção receba eventos de alteração.Pensei em criar uma extensão CDI.

Capturamos o evento ProcessAnnotatedType e procuramos todos os campos que possuem uma anotação personalizada nos pontos de injeção de campo:

 <T> void pat(@Observes ProcessAnnotatedType<T> event, BeanManager bm) {
   final AnnotatedType<T> target = event.getAnnotatedType();

   for (AnnotatedField<? super T> field : target.getFields())
     if (field.isAnnotationPresent(Value.class)) {  // ignore that I don't check @Inject here for the moment
        CtClass wrapper = pool.get(target.getJavaClass().getName());
        ConstPool cp = wrapper.getClassFile().getConstPool();

        CtMethod m = CtNewMethod.make(....)
        ....
        wrapper.addMethod(m);

        event.setAnnotatedType(bm.createAnnotatedType(wrapper.toClass()));
     }
 }

Depois disso, ele pegou todos os pontos de injeção dos campos e substituiu o WeldField subjacente por um novo campo correspondente ao tipo "wrapper".Caso contrário, a validação do bean falhará.

Mas isso só funciona para configuração de coisas durante a inicialização, não quando, por exemplo, o Arquillian usa o Bean Manager para inicializar uma classe que injeta um dos meus "wraps".As coisas falham porque o Bean Resolver usa o Type como uma chave hash para encontrar beans.

Basicamente não creio que possa "mascarar" uma classe que é anotada (transformada em bean) pelo CDI com um método extra para receber eventos customizados.Teria sido legal, mas um tipo é um tipo (ou seja,não tenho ideia de como fazer proxy ou falsificar o equals/hashCode).

Foi útil?

Solução

Entendi.Acontece que a função de valor de computação (extensão do Google) dentro do resolvedor TypeSafeBeanResolver (pelo menos a implementação do CDI Weld) é inteligente.Se eu apenas estender a classe:

 CtClass wrapper = pool.makeClass(target.getJavaClass().getName()+"Proxy");
 wrapper.setSuperclass(pool.get(target.getJavaClass().getName()));
 .....
 final AnnotatedType<T> other = bm.createAnnotatedType(wrapper
                    .toClass());

então tudo funciona bem.Testado a captura de um evento em um bean.Postará o código em um Gist com um comentário.

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