AspectJ and CDI

前端 未结 2 1066
误落风尘
误落风尘 2021-01-14 04:20

I\'m trying to figure out a way to inject a bean into an aspect.

I mean

public class Greeter {
    public String greet(String name) {....}
}

...

pu         


        
2条回答
  •  无人及你
    2021-01-14 05:02

    Thanks to the help of the community, I managed to come out with a solution for both the problems. Leaving track here.

    PART ONE - aspectjrt.jar in deployment

    First, added Shrinkwrap to my dependencies:

    
        org.jboss.shrinkwrap.resolver
        shrinkwrap-resolver-api-maven
        test
    
    
        org.jboss.shrinkwrap.resolver
        shrinkwrap-resolver-impl-maven
              test
    
    
           org.jboss.shrinkwrap.resolver
           shrinkwrap-resolver-impl-maven-archive
          test
    
    

    is not needed: Arquillian's BOM - already included - will take care of that.

    Then add aspectj to deployment classpath:

    @RunWith(Arquillian.class)
    public class ArquillianTest {
        private static final String[] DEPENDENCIES = {
            "org.aspectj:aspectjrt:1.8.7"
        };
    
        @Deployment
        public static JavaArchive createEnvironement() {
            JavaArchive lib = ShrinkWrap.create(JavaArchive.class, "libs.jar");
            for (String dependency : DEPENDENCIES) {
                lib.merge(Maven.resolver().resolve(dependency).withTransitivity().asSingle(JavaArchive.class));
            }
    
            JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
                // create you deployment here
                .as(JavaArchive.class);
    
            JavaArchive toBeDeployed = jar.merge(lib);
    
            return toBeDeployed;
        }
    
        // other stuff, like tests
    
    }
    

    PART TWO: Injecting a bean into an aspect

    After further inquiries I think simas_ch was correct in saying that CDI does not inject beans into aspects.

    Came out with a workaround: adding an @Injected member into a bean via the aspect.

    public interface Advised {
        String buildGreeting(String name);
    }
    
    public class AdvisedImpl implements Advised {
        String buildGreeting(String name) {
            return "ADVISED";
        }
    }
    
    public class Greeter {
        public String greet(String name) {
            return "Hello, " + name + ".";
        }
    }
    
    ...
    
    public aspect GreeterAspect {
        @Inject
        private Greeter Advised.greeter; // adding the member to the interface / class. No need for getters / setters
    
        private pointcut pc() : execution(* x.y.z.Advised.buildGreeting(String));
    
        String around(Advised adv, String name) : pc() && target(adv) && args(name) {
            log.debug("Aspect is about to say something...");
            String result = proceed(adv, name) + " - " + adv.greeter.greet(name);
            log.debug("Aspect said: '" + result + "'");
            return result;
        }
    }
    

    Given the test

    @Test
    public void test() {
        assertThat(advised, not(is(nullValue())));
        assertThat(advised.buildGreeting("Stefano"), equalToIgnoringCase("advised - hello, stefano."));
    }
    

    it succeeds.

提交回复
热议问题