링크: http://hannesdorfmann.com/annotation-processing/annotationprocessing101/

링크: https://deors.wordpress.com/2011/10/08/annotation-processors/

posted by 뚱2

링크: https://github.com/FasterXML/jackson-datatype-hibernate


Hibernate Entity를 바로 Json으로 변환할때 Lazy 프로퍼티로 예외가 발생한다.

그럴때 @JsonIgnore를 하면 되기는 한데 케이스 바이 케이스로 항상 어노테이션을 설정할수 없다.

그럴때 참 편하게 도와준다.

'Java > Jackson' 카테고리의 다른 글

[Jackson] Jackson documentation  (0) 2014.01.19
posted by 뚱2

설명보다 제목적기가 더 힘들다.


Bean을 일일이 설정하기 힘들기 때문에 SpringMVC에서는 MVC 구분에 맞춰서

@Controller, @Service, @Repository가 있다. 또한 이와 관계없이 @Component  어노테이션이 존재한다.


나는 보통 @Controller는 servlet context에 설정하고

@Service, @Repository, @Component는 root context에 설정한다.


그래서 servlet-context에 아래와 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />

    </context:component-scan>


그리고 root-context에는 다음과 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />

    </context:component-scan>



그런데 이번에 @Component 어노테이션을 사용할 일이 있어서 사용했더니 이개 두번 생성된다.

servlet context와 root context에서 같이 생성되는 현상이 발생했다.


그래서 servlet context를 아래와 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component" />

    </context:component-scan>


그랬더니 페이지를 찾을 수 없다는 404에러가 발생했다.

원인은 컨트롤러 빈이 로딩이 되지 않는것이였다.

원인을 찾아보니 @Controller 어노테이션의 소스에서 찾았다.

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Component

public @interface Controller {


/**

* The value may indicate a suggestion for a logical component name,

* to be turned into a Spring bean in case of an autodetected component.

* @return the suggested component name, if any

*/

String value() default "";


}

Controller 어노테이션이 Component 어노테이션을 사용하고 있는 것


그리고 최종으로 아래와 같이 수정해서 해결했다.

servlet context 

    <context:component-scan base-package="com.ddoong2" use-default-filters="false">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

    </context:component-scan>


root context

    <context:component-scan base-package="com.ddoong2" use-default-filters="false">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />

    </context:component-scan>


component-scan의 프로퍼티중에 use-default-filters의 기본값은 true 이다.

이 부분을 false로 하고 설정을 하면 다른 필터는 로딩되지 않고 순수하게 설정된 부분만 필터링이된다.

posted by 뚱2

링크 : http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html

posted by 뚱2

링크 : http://isagoksu.com/2009/development/java/creating-custom-annotations-and-making-use-of-them/ 

 

How to Create a Custom Annotations?

There are a lot of documentation about this part in the Internet. All you have to do is basically creating an annotation class like below:

public @interface Copyright {
    String info() default "";
}

And that’s it. Now it’s ready to use! Now you can put copyright information to your classes :) Since we didn’t define any @Target, you can use this annotation anywhere in your classes by default. If you want your annotation to be only available for class-wise or method-wise, you should define @Target annotation. Here is a little table of what options are available:

  • @Target(ElementType.PACKAGE), package header
  • @Target(ElementType.TYPE), class header
  • @Target(ElementType.CONSTRUCTOR), constructor header
  • @Target(ElementType.METHOD), method header
  • @Target(ElementType.FIELD), for class fields only
  • @Target(ElementType.PARAMATER), for method parameters only
  • @Target(ElementType.LOCAL_VARIABLE), for local variables only

If you want your annotation to be available in more than one place, just use array syntax as in:

@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

One thing you may already notice is annotations are interfaces, so you don’t implement anything in them.

How to Make Use of Your Custom Annotations?

Up to here, you can find lots of examples. Okaaay, now let’s do something useful :) For instance, let’s re-implement JUnit’s @Test annotation. As you guys already know, @Test annotation is a marker annotation. Basically it marks the method as test method. If you’re expecting any exceptions, you would set expect attribute in the annotation. You can try anything here, I’m just using this example since everyone knows how @Test annotation works.

First let’s define our annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
    Class expected();
}

You might notice that I used @Retention. This annotation marks our annotation to be retained by JVM at runtime. This will allow us to use Java reflections later on.

Now we need to write our annotation parser class. This class will parse our annotation and trigger some other invocations related to what we want. Keep in mind that if you have more than one custom annotation, then it’s also wise to have separate parsers for each annotation you define. So I’ll create one for this! The basic idea behind the annotation parser is using Java reflections to access the annotation information/attributes etc. So here is an example parser for our @Test annotation:

public class TestAnnotationParser {
    public void parse(Class<?> clazz) throws Exception {
        Method[] methods = clazz.getMethods();
        int pass = 0;
        int fail = 0;

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            try {
                method.invoke(null);
                pass++;
            } catch (Exception e) {
                fail++;
            }
        }
    }
}

}

That’s all you need. You parser is ready to use too. But wait a minute, we didn’t implement anything about the annotation attributes. This part is a bit tricky. Because you cannot directly access those attributes from the object graph. Luckily invocation helps us here. You can only access these attributes by invoking them. Sometimes you might need to cast the class to the annotation type too. I’m sure you’ll figure out when you see it:) Anyways here is a bit more logic to take our expected attribute into account:

// ...
// this is how you access to the attributes
Test test = method.getAnnotation(Test.class);
// we use Class type here because our attribute type
// is class. If it would be string, you'd use string
Class expected = test.expected();
try {
    method.invoke(null);
    pass++;
} catch (Exception e) {
    if (Exception.class != expected) {
        fail++;
    } else {
        pass++;
    }
}
// ...

Now everything is ready to use. Below example demonstrates how you use Parser with your test classes:

public class Demo {
    public static void main(String [] args) {
        TestAnnotationParser parser = new TestAnnotationParser();
        parser.parse(MyTest.class);
        // you can use also Class.forName 
        // to load from file system directly!
    }
}

Yeah, I hope you enjoyed. Don’t hesitate to put some comments down if you’ve a better approach? Thanks! Here is the full parser class implementation:

public class TestAnnotationParser {
    public void parse(Class<?> clazz) throws Exception {
        Method[] methods = clazz.getMethods();
        int pass = 0;
        int fail = 0;

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            // this is how you access to the attributes
            Test test = method.getAnnotation(Test.class);
            Class expected = test.expected();
            try {
                method.invoke(null);
                pass++;
            } catch (Exception e) {
                if (Exception.class != expected) {
                    fail++;
                } else {
                    pass++;
                }
            }
        }
    }
}

}

Edit: Also after receiving some emails, I guess I should add a full working example :) So here is one. Just copy paste and run the show :)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
    String info() default "";
}

class Annotated { @Test(info = "AWESOME") public void foo(String myParam) { System.out.println("This is " + myParam); } }

class TestAnnotationParser { public void parse(Class clazz) throws Exception { Method[] methods = clazz.getMethods();

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            Test test = method.getAnnotation(Test.class);
            String info = test.info();

            if ("AWESOME".equals(info)) {
                 System.out.println("info is awesome!");
                 // try to invoke the method with param
                 method.invoke(
                    Annotated.class.newInstance(), 
                    info
                 );
            }
        }
    }
}

}

public class Demo { public static void main(String[] args) throws Exception { TestAnnotationParser parser = new TestAnnotationParser(); parser.parse(Annotated.class); } }

'Java > Java' 카테고리의 다른 글

[Java] jar 파일 실행 시키기  (0) 2013.04.07
[Java] JDK Download  (0) 2013.04.02
[Java] Class<?> 의 의미?  (0) 2013.01.21
[Java] JConsole 연결 옵션  (0) 2013.01.05
[Java] Java 모니터링 툴 VisualVM Download  (0) 2012.12.28
posted by 뚱2

'Java > Java' 카테고리의 다른 글

[Java] Java Dynamic method call  (0) 2012.02.09
[Java] map sort  (0) 2012.02.02
[Java] instanceof 연산자  (0) 2011.11.28
[Java] 날짜표시 YYMMDDHH24MI  (0) 2011.11.21
[Java] JDK와 JRE  (0) 2011.04.27
posted by 뚱2