Skip to content

Commit

Permalink
Merge pull request quarkusio#19776 from manovotn/interceptionComplexTest
Browse files Browse the repository at this point in the history
Arc - pre-destroy and post construct shouldn't be considered as candidates for around invoke interception
  • Loading branch information
manovotn authored Aug 31, 2021
2 parents 2f02e97 + 28fbb44 commit b371fef
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,10 @@ public boolean test(MethodInfo method) {
// The algorithm we use to detect these methods is best effort, i.e. there might be use cases where the detection fails
return hasImplementation(method);
}
if (method.hasAnnotation(DotNames.POST_CONSTRUCT) || method.hasAnnotation(DotNames.PRE_DESTROY)) {
// @PreDestroy and @PostConstruct methods declared on the bean are NOT candidates for around invoke interception
return true;
}
if (isOverridenByBridgeMethod(method)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.quarkus.arc.test.interceptors.complex;

import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.test.ArcTestContainer;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class MultipleInterceptionTypesTogetherTest {

@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(MyBinding.class, SomeBean.class, MyInterceptor.class);

@Test
public void testInterceptionIsInvokedWhenAppropriate() {
SomeBean.reset();
MyInterceptor.reset();
// assert initial state
Assertions.assertEquals(false, SomeBean.postConstructInvoked.get());
Assertions.assertEquals(false, SomeBean.preDestroyInvoked.get());
Assertions.assertEquals(false, MyInterceptor.aroundConstructInvoked.get());
Assertions.assertEquals(false, MyInterceptor.postConstructInvoked.get());
Assertions.assertEquals(false, MyInterceptor.preDestroyInvoked.get());
Assertions.assertEquals(false, MyInterceptor.aroundInvokeInvoked.get());
// create bean instance, no method was invoked so far
InstanceHandle<SomeBean> instance = Arc.container().instance(SomeBean.class);
SomeBean bean = instance.get();
// assert lifecycle callback were invoked but no around invoke was triggered
Assertions.assertEquals(true, SomeBean.postConstructInvoked.get());
Assertions.assertEquals(false, SomeBean.preDestroyInvoked.get());
Assertions.assertEquals(true, MyInterceptor.aroundConstructInvoked.get());
Assertions.assertEquals(true, MyInterceptor.postConstructInvoked.get());
Assertions.assertEquals(false, MyInterceptor.preDestroyInvoked.get());
Assertions.assertEquals(false, MyInterceptor.aroundInvokeInvoked.get());
// invoke bean method and assert around invoke was triggered
bean.ping();
Assertions.assertEquals(true, SomeBean.postConstructInvoked.get());
Assertions.assertEquals(false, SomeBean.preDestroyInvoked.get());
Assertions.assertEquals(true, MyInterceptor.aroundConstructInvoked.get());
Assertions.assertEquals(true, MyInterceptor.postConstructInvoked.get());
Assertions.assertEquals(false, MyInterceptor.preDestroyInvoked.get());
Assertions.assertEquals(true, MyInterceptor.aroundInvokeInvoked.get());
// trigger bean destruction and assert lifecycle interceptors were triggered
instance.destroy();
Assertions.assertEquals(true, SomeBean.postConstructInvoked.get());
Assertions.assertEquals(true, SomeBean.preDestroyInvoked.get());
Assertions.assertEquals(true, MyInterceptor.aroundConstructInvoked.get());
Assertions.assertEquals(true, MyInterceptor.postConstructInvoked.get());
Assertions.assertEquals(true, MyInterceptor.preDestroyInvoked.get());
Assertions.assertEquals(true, MyInterceptor.aroundInvokeInvoked.get());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.arc.test.interceptors.complex;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
public @interface MyBinding {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.quarkus.arc.test.interceptors.complex;

import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Priority;
import javax.interceptor.AroundConstruct;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Interceptor
@Priority(1)
@MyBinding
public class MyInterceptor {

public static AtomicBoolean preDestroyInvoked = new AtomicBoolean(false);
public static AtomicBoolean postConstructInvoked = new AtomicBoolean(false);
public static AtomicBoolean aroundConstructInvoked = new AtomicBoolean(false);
public static AtomicBoolean aroundInvokeInvoked = new AtomicBoolean(false);

@PreDestroy
public void preDestroy(InvocationContext ic) {
preDestroyInvoked.set(true);
}

@PostConstruct
public void postConstruct(InvocationContext ic) {
postConstructInvoked.set(true);
}

@AroundConstruct
public void aroundConstruct(InvocationContext ic) throws Exception {
aroundConstructInvoked.set(true);
ic.proceed();
}

@AroundInvoke
public Object aroundInvoke(InvocationContext ic) throws Exception {
aroundInvokeInvoked.set(true);
return ic.proceed();
}

public static void reset() {
preDestroyInvoked.set(false);
postConstructInvoked.set(false);
aroundConstructInvoked.set(false);
aroundInvokeInvoked.set(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.arc.test.interceptors.complex;

import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;

@Singleton
@MyBinding
public class SomeBean {

public static AtomicBoolean preDestroyInvoked = new AtomicBoolean(false);
public static AtomicBoolean postConstructInvoked = new AtomicBoolean(false);

@PreDestroy
public void preDestroy() {
preDestroyInvoked.set(true);
}

@PostConstruct
public void postConstruct() {
postConstructInvoked.set(true);
}

public void ping() {

}

public static void reset() {
preDestroyInvoked.set(false);
postConstructInvoked.set(false);
}
}

0 comments on commit b371fef

Please sign in to comment.