カスタムSpring注釈beanの命名ポリシー

4310 ワード

プロジェクトがspringを必要とする業務に関するbeanはxmlファイルに書かれていません.プロジェクトはモジュールの一つのモジュールから提出されたので、提出時にxmlファイルを修正したくないので、springの注釈Serviceを使いました.
 たとえば:
      Javaコード
1 @Service("TestService")  
2 public class TestService {
3   }  
   これは以下と同じです
Xmlコード 
1 <bean id="TestService" class="TestService"/>  
   springはclassipath内でTestServiceなどのラベルが付いたクラスをスキャンします.スキャンコンポーネントの構成は以下の通りです.
  Xmlコード 
1 <!-- sdp-service         -->  
2 
3 <context:component-scanbase-package="org.sdp"/>
 以上の配置を加えると、springは自動的にorg.sdpファイルの下のマークにコメントが付いているクラスをスキャンします.
 以上の配置は「完璧」に見えますが、プロジェクトが少し大きいと問題が発生します.みんなはspringのbeanのidが唯一であることを知っています.もし二人の同僚がコードを書くと同じbeanの名前を書くことができます.
この問題を解決する一つの考えはbeanの名前をクラスの全パスに修正することです.例えばorg.sdp.Aとcomp.bey.A.
springのデフォルトのbean命名戦略を修正すればいいです.
AnnotationBeanNameGeneratorはbeanのデフォルトの命名戦略で、彼はBeanNameGeneratorインターフェースを実現しました.Serviceでは、beanの名前を書かないとデフォルトの名前はクラス名ですが、最初の文字は小文字です.
たとえば:
 Htmlコード 
1 com.xyz.FooServiceImpl -> fooServiceImpl  
springのソースコードを観察すると、buildDefaultBeanName法はまずbean名前の小文字の役割を果たしている.
Javaコード 
1 protected String buildDefaultBeanName(BeanDefinition definition) {  
2        String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());  
3         return Introspector.decapitalize(shortClassName);  
4 
5     }  
したがって、AnnotationBeanNameGeneratorから継承されたクラスを書くことができます.
 Javaコード 
1 public class SdpAnnotationBeanNameGenerator extends AnnotationBeanNameGenerator {        
2 @Override      
3 protected String buildDefaultBeanName(BeanDefinitiondefinition) {          
4 return definition.getBeanClassName();    
5  }  
6 }  
私の変更コード:
 1 @Override
 2     protected String buildDefaultBeanName(BeanDefinition definition) {
 3         String className =definition.getBeanClassName();  
 4     
 5         className=className.substring(className.lastIndexOf(".")+1);
 6         if(className.toLowerCase().endsWith("impl")){
 7             className=className.substring(0, className.length()-4);
 8         }
 9         if((className.toLowerCase().endsWith("service")||className.toLowerCase().endsWith("dao"))==false){
10             return super.buildDefaultBeanName(definition);
11         }
12         
13     
14         className=className.substring(0,1).toLowerCase() + className.substring(1);
15         return className;
16     }
 
スキャンの設定には、自分の名前ポリシークラスを追加する必要があります.
Xmlコード 
1 <!-- sdp-service         -->  
2 <context:component-scan base-package="org.sdp" name-generator="org.sdp.spring.SdpAnnotationBeanNameGenerator" />  
以上の配置によって、業務関連のbeanはbeanの名前を書かなくてもいいです.Application Contact.getBen(「クラスのフルパス」)はクラスの実例を得ることができます.
spring 2.5なら終わりですが、spring 3.0は完璧にgetBenを提供しました.一般型を使用しているので、一つの業務クラスのクラスに入ると、ゲトビーンはこのような実例を返します.
強制的にタイプを変換しました.
1 public static <T>T getService(String classFullName) throws ClassNotFoundException,BeansException{  
2     Class<T> requiredType=(Class<T>)Class.forName(classFullName);  
3         return SdpContext.getContext().getBean(classFullName,requiredType);     }  
強制変換タイプコード:
  Javaコード 
1 TestService testService2=(TestService ) SdpContext.getContext().getBean("TestService ");  
2 System.out.println(testService2); 
改善されたコード:
 Javaコード 
1 @Service  
2 public class TestService {    }  
Javaコード 
1 TestService testService=SdpContext.getService("org.sdp.context.TestService");  
2 System.out.println(testService); 
 
抜粋:http://yunzhongxia.iteye.com/blog/898433