カスタムSpring注釈beanの命名ポリシー
4310 ワード
プロジェクトがspringを必要とする業務に関するbeanはxmlファイルに書かれていません.プロジェクトはモジュールの一つのモジュールから提出されたので、提出時にxmlファイルを修正したくないので、springの注釈Serviceを使いました.
たとえば:
Javaコード
Xmlコード
Xmlコード
以上の配置は「完璧」に見えますが、プロジェクトが少し大きいと問題が発生します.みんなはspringのbeanのidが唯一であることを知っています.もし二人の同僚がコードを書くと同じbeanの名前を書くことができます.
この問題を解決する一つの考えはbeanの名前をクラスの全パスに修正することです.例えばorg.sdp.Aとcomp.bey.A.
springのデフォルトのbean命名戦略を修正すればいいです.
AnnotationBeanNameGeneratorはbeanのデフォルトの命名戦略で、彼は
たとえば:
Htmlコード
Javaコード
Javaコード
スキャンの設定には、自分の名前ポリシークラスを追加する必要があります.
Xmlコード
spring 2.5なら終わりですが、spring 3.0は完璧にgetBenを提供しました.一般型を使用しているので、一つの業務クラスのクラスに入ると、ゲトビーンはこのような実例を返します.
強制的にタイプを変換しました.
Javaコード
Javaコード
抜粋:http://yunzhongxia.iteye.com/blog/898433
たとえば:
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