I have three classes: Main with a method main , an interceptor class with an intercept method, and a class for trying to intercept a method call.


one.

 package com.dugin.rostislav.test; public class Main { public static void main(String[] args) { new TestInterceptor().test(); } } 

2

 package com.dugin.rostislav.test; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; public class SimpleInterceptor { @AroundInvoke public Object catchCall(InvocationContext context) throws Exception { System.out.println("call catched!"); return context.proceed(); } } 

3

 package com.dugin.rostislav.test; import javax.interceptor.Interceptors; public class TestInterceptor { @Interceptors(SimpleInterceptor.class) public void test() { System.out.println("test"); } } 

Dependency in pom.xml :

  <dependency> <groupId>javax.interceptor</groupId> <artifactId>javax.interceptor-api</artifactId> <version>1.2</version> </dependency> 

I expected that before calling the test() method, the catchCall() method would be called, but the catchCall () method was called immediately. Why is this happening and how to intercept the call?

  • one
    The spoiler by itself does not intercept anything. This all makes the framework, and then only on the objects controlled by this framework. That put the java-ee tag, And where are the signs of this java-ee in your program? What is the TestInterceptor class? Is it an EJB or CDI? On all this, even with java-ee, it does not wake up! A standalone application generally requires initializing a two-sheet framework, which is not noticeable in your Main. - Sergey

1 answer 1

Understand, annotations themselves do not do any magic. Always need the appropriate handler.

JavaEE dictates that all necessary handlers be included in the application server that complies with this specification. Standalone JavaEE applications are not covered.

However, you can use the same CDI in a regular application with some effort. Then you can, in principle, take advantage of all the charms of the framework.

 Weld weld = new Weld(); WeldContainer container = weld.initialize(); 

Weld - one of the implementation of CDI, and the only exemplary (reference implementation)

But the objects must be managed by this CDI. This usually means that there should be no new TestInterceptor() . CDI does not know your new TestInterceptor() , will not call for any interceptors for it. He knows only those objects that he creates himself.

 TestInterceptor ti = container.instance().select(TestInterceptor.class).get(); ti.test(); 

When a new object is created via CDI, then CDI can intercept calls to the methods of its object. Seeing the annotation of the interceptor, it will cause the interceptor.
In fact, when an object is received via CDI, the object is replaced in some way. In the simplest case, it will be a proxy object that is not very visible from the present. The methods of this proxy are modified in such a way that they will cause the spoilers, if any, and then the method of the original object.

  • Mdja ... After the libraries that work on code generation, even a thought hasn’t crept into the head, that it itself is not processed ... - user189127