I want to simplify this
#Controller
#Scope("prototype")
public class Struts2ActionClass{
...
}
to this
#Struts2Action
public class Struts2ActionClass{
...
}
attempt to avoid foggetting the #Scope("prototype")
Dose anyone have any idea?
Update:
I did this copy the code of #Controller,it seems worked.
#Target({ ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Controller
#Scope("prototype")
public #interface Struts2Action {
}
But why?
I did this copy the code of #Controller,it seems worked.
#Target({ ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Controller
#Scope("prototype")
public #interface Struts2Action {
}
It works because that's the way to combine annotations. So now you don't need to write every annotation (Controller, Scope etc.), just the parent one (Struts2Action)
Related
I've a meta-annotation that annotates my test classes:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#SpringBootTest
#BootstrapWith(MyOwnTestContextBootstrapper.class)
public #interface IntegrationTest {
.....
And my test class looks like:
#IntegrationTest
class CreateSubscriptionServiceTest {
#Autowired
.......
Then I got this exception:
found multiple declarations of #BootstrapWith
details:
java.lang.IllegalStateException: Configuration error: found multiple declarations of #BootstrapWith for test class [com.my.project.CreateSubscriptionServiceTest]: [#org.springframework.test.context.BootstrapWith(value=com.my.project.MyOwnTestContextBootstrapper), #org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]
at org.springframework.test.context.BootstrapUtils.resolveExplicitTestContextBootstrapper(BootstrapUtils.java:176)
at org.springframework.test.context.BootstrapUtils.resolveTestContextBootstrapper(BootstrapUtils.java:130)
at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:122)
at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$4(ExtensionValuesStore.java:86)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.computeValue(ExtensionValuesStore.java:223)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:211)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.evaluate(ExtensionValuesStore.java:191)
....
I figured the answer.
Replace #SpringBooTest with #ExtendWith(SpringExtension.class) so the meta-annotation looks like:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(SpringExtension.class)
#BootstrapWith(MyOwnTestContextBootstrapper.class)
public #interface IntegrationTest {
.....
I have an annotation
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface A {
Class<?> value();
}
and another annotation that uses #AliasFor
#A (Void.class)
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface B {
#AliasFor(annotation = A.class)
Class<?> value();
}
which is used on class
#B(D.class)
public class C implements D {
}
If I have an instance of C, how can I programatically resolve A.value() to Class<D>?
I'm trying to synthesise the annotation with AnnotationUtils but when I retrieve the value I'm constantly getting Class<Void>.
After some digging around, the answer is that I've used the wrong class. Instead of AnnotationUtils it can be done with AnnotatedElementUtils:
#Test
public void shouldFindAliasedValue() {
Class<?> actual = AnnotatedElementUtils.findMergedAnnotation(C.class, A.class).value();
then(actual).isEqualTo(D.class);
}
I have a weird problem trying to add a parameterized logging interceptor to my Java EE 7 application.
I went from a class interceptor using the #Interceptors annotation to writing a custom interceptor binding. What I have not looks like this...
The annotation
#Inherited
#InterceptorBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.TYPE,
ElementType.METHOD
})
public #interface LogMethodCall {
MethodLogger logLevel() default MethodLogger.INFO;
}
The interceptor
#Slf4j
#LogMethodCall
#Interceptor
#Priority(Interceptor.Priority.APPLICATION)
public class ActionInterceptor {
#AroundInvoke
protected Object protocolInvocation(final InvocationContext ic) throws Exception {
log.info(
"{}: <{}> called. Parameters={}",
ic.getTarget().getClass().getName(),
ic.getMethod().getName(),
ic.getParameters());
return ic.proceed();
}
}
The usage
#GET
#Path("/{account}")
#LogMethodCall
public void inboxes(#Suspended AsyncResponse response, #PathParam("account") String account) {
...
}
When I use it like this everything works OK.
Buy when I try to use change the logLevel and use
#LogMethodCall(logLevel=MethodLogger.DEBUG)
then my interceptor never gets called.
What am I missing here? Why setting the annotation value breaks the code?
If you say that your interceptor is catching only when the value is INFO, you can consider to put your logLevel() attribute as #Nonbinding.
By default, qualifier arguments are considered for matching bean qualifiers to injection point qualifiers. A #Nonbinding argument is not considered for matching.
Try this:
#Inherited
#InterceptorBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.TYPE,
ElementType.METHOD
})
public #interface LogMethodCall {
#Nonbinding MethodLogger logLevel() default MethodLogger.INFO;
}
Searchable.java
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
public #interface Searchable { }
Obj.java
public class Obj {
#Searchable
String myField;
}
void main(String[] args)
Annotation[] annotations = Obj.class.getDeclaredField("myField").getAnnotations();
I would expect annotations to be containing my #Searchable. Though it is null. According to documentation, this method:
Returns all annotations present on this element. (Returns an array of length zero if this element has no annotations.) The caller of this method is free to modify the returned array; it will have no effect on the arrays returned to other callers.
Which is even more weird (to me), since it returns null instead of Annotation[0].
What am I doing wrong here and more important, how will I be able to get my Annotation?
I just tested this for you, and it just works:
public class StackOverflowTest {
#Test
public void testName() throws Exception {
Annotation[] annotations = Obj.class.getDeclaredField("myField").getAnnotations();
System.out.println(annotations[0]);
}
}
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
#interface Searchable {
}
class Obj {
#Searchable
String myField;
}
I ran it, and it produces the following output:
#nl.jworks.stackoverflow.Searchable()
Can you try running the above class in your IDE? I tried it with IntelliJ, openjdk-6.
Your code is correct. The problem is somewhere else. I just copied and run your code and it works.
It is possible that you are importing the wrong Obj class in your code you may want to check that first.
In my case, i had forgotten to add
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
to the method, so in the end it should look like:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
}
In my case, the error was in my own annotation.
I fixed a couple of things, and it finally ended up like this:
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Target( { METHOD, FIELD, ANNOTATION_TYPE })
#Retention(RUNTIME)
public #interface MyAnnotation{
}
It works now
I recently found that ( http://www.javabeat.net/articles/30-annotations-in-java-50-2.htmlthe )syntax of the #Override annotation is
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.RUNTIME)
public #interface Override
{
}
But I think the following.Since it can be applied only to methods and since it inform this to compiler.
#Retention(RetentionPolicy.CLASS
#Target(ElementType.METHOD)
public #interface Override
{
}
Please tell me which one is correct. Please explain, if i am wrong.
Thanks.
Both are wrong; it is defined (according to javadoc) as
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.SOURCE)
public #interface Override