Develop with pleasure!

福岡でCloudとかBlockchainとか。

JSR-250とSpringFramework

SpringFramework2.5はアノテーションによるインジェクションの設定が可能。折角なのでApplicationContext.xmlにBean定義をゴリゴリ書くのを止めて、アノテーション設定にしてみる。

@Autowiredで自動インジェクションされるようになったが、@Autowiredって
org.springframework.beans.factory.annotationパッケージに存在してて、Spring依存じゃん…。

アノテーションを付加したオブジェクトはPOJOかという議論はあるが、さすがに、このアノテーションはSpring依存になってしまうので、折角のPOJOがゲンナリ…。まぁ、StrutsのZeroConfigurationのPOJOも一緒なんだけど。

何とかならんかと思ったら、こういった共通的なアノテーションまとめようよってことで、JSR-250としてCommon Annotations for the Java Platformって仕様が策定されてるじゃないですか。Spring2.5もJSR-250に対応してるので、JSR-250の
javax.annotation.Resource
を利用すればOK。が、これって適用されてるのが、JavaEE5 or JavaSE6〜でJavaSE5じゃアウト。ただ、JCPのJSR-250のサイトからjsr250-api.jarがダウンロードできるので、これを組み込んでやればOK。

問題はBean定義。これは対象となるJSR-250のアノテーションは無い。でも、context:component-scanでBean定義を起こす対象を自動走査するし、Bean定義のインクルード対象を設定するが、これにSpringのアノテーション定義以外に、正規表現やクラスの指定、アノテーションの指定、aspectj形式の指定ができるので、正規表現で *Implクラスを対象にとしてば該当するクラスがBean定義される。

ちなみに、Bean定義のIDはクラス名の先頭小文字になる。この命名ルールを変更したい場合は、name-generatorプロパティで、命名クラスを自作できる。
とりあえず、クラス名の先頭小文字+Implを削除 = インタフェース名の先頭小文字にしてみた。

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;

public class GenericBeanNameGenerator implements BeanNameGenerator {

    public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
        String beanClassName = beanDefinition.getBeanClassName();
        beanClassName = beanClassName.substring(beanClassName.lastIndexOf(".") + 1, beanClassName.length()).replace("Impl", "");
        String first = beanClassName.substring(0, 1).toLowerCase();
        return first + beanClassName.substring(1, beanClassName.length());
    }

}