`

自定义Spring注解bean的命名策略

阅读更多
由于项目的需要spring的业务相关的bean不是写在xml文件中,因为项目是一个模块一个模块提交的,提交的时候不想修改xml文件,因此就用到了spring的注解Service。

例如:

      Java代码

1 @Service("TestService") 
2 public class TestService {
3   } 
   这等同于:

1 <bean id="TestService" class="TestService"/> 
   spring会在classpath里面扫描标记有TestService等标签的类,扫描组件的配置如下:

  Xml代码

1 <!-- sdp-service主要是注入服务类 --> 
2
3 <context:component-scanbase-package="org.sdp"/>
加上以上的配置后,spring会自动的扫描org.sdp文件下的标记有注释的类。

以上的配置看似很“完美”,其实如果项目稍微大时就会出现问题,大家都知道spring的bean的id必须唯一,如果两个人同事写代码就有可以造成写同样的bean名称。

解决这个问题的一个思路是把bean的名称修改为 类的全路径,例如org.sdp.A 和com.bey.A 。

只要修改spring默认的bean命名策略就可以了。

AnnotationBeanNameGenerator是bean的默认命名策略,他实现了BeanNameGenerator接口。在Service里面,如果不写bean的名称,那么默认的名曾是类名,但是第一个字母是小写的。

例如:

Html代码

1 com.xyz.FooServiceImpl -> fooServiceImpl 
观察spring的源代码发现,buildDefaultBeanName方法首先了bean名称小写的作用。

1 protected String buildDefaultBeanName(BeanDefinition definition) { 
2        String shortClassName = ClassUtils.getShortName(definition.getBeanClassName()); 
3         return Introspector.decapitalize(shortClassName); 
4
5     } 
因此,可以写一个类继承自AnnotationBeanNameGenerator,重写buildDefaultBeanName方法。

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     }
复制代码


在扫描配置中需要添加自己的命名策略类:

1 <!-- sdp-service主要是注入服务类 --> 
2 <context:component-scan base-package="org.sdp" name-generator="org.sdp.spring.SdpAnnotationBeanNameGenerator" /> 
通过以上配置,业务相关的bean不用写bean的名称了,ApplicationContext.getBean("类的全路径")就可以得到类的实例了。

如果是spring2.5则就结束了,但是spring3.0为完美提供了getBean(name,requiredType);使用了泛型,因此只要传入一个业务类的Class,getBean就返回此类的实例,而不用在

强制转换类型了。

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 {    } 
1 TestService testService=SdpContext.getService("org.sdp.context.TestService"); 
2 System.out.println(testService);


摘自:http://yunzhongxia.iteye.com/blog/898433
分享到:
评论

相关推荐

    这一次搞懂Spring自定义标签以及注解解析原理说明

    例如,开发者可以通过自定义标签来定义一组特定的注解策略,或者在处理某些特定场景时,通过注解来控制Bean的行为。 总结起来,Spring的自定义标签解析是通过`NamespaceHandler`机制实现的,而注解解析则依赖于类...

    这一次搞懂Spring自定义标签以及注解解析原理说明.docx

    在Spring框架中,自定义标签和注解解析是核心功能之一,它们允许开发者根据特定需求扩展和定制Spring的配置方式。本文将深入探讨这两个概念的解析原理,帮助读者理解Spring如何处理自定义标签和注解。 首先,让我们...

    Spring中与Bean相关的接口

    然而,这两种接口的方法命名约定可能会导致代码过于依赖Spring,因此Spring 4.0引入了`@PostConstruct`和`@PreDestroy`注解作为替代,它们更符合JSR-250规范,可以更好地与其他Java EE环境兼容。 此外,`...

    借助spring自定义命令执行器

    - 最后,为了使Spring能够识别并使用我们的`CustomCommandExecutor`,需要在配置文件或使用注解配置中注册这个bean。 5. **应用场景**:自定义命令执行器常用于以下场景: - 当需要在多个地方调用同一个方法,但...

    spring 的Annotation方式

    这里,`MyCustomNameGenerator`是一个实现了`BeanNameGenerator`接口的类,用于提供定制化的Bean命名策略。 #### 结论 Spring框架的注解驱动依赖注入极大地简化了应用的配置,提高了代码的可读性和可维护性。通过...

    使用了自定义springboot-starter组件的示例项目【study-springboot】

    在这个项目中,我们应该能看到对自定义Spring Boot Starter的引用以及其他必要的依赖。 5. `src`:源代码目录,通常包含`main`和`test`两个子目录,分别存放主代码和测试代码。在`main`下,会有Java源码和资源文件...

    spring中bean id相同引发故障的分析与解决

    不过,仍需确保Bean的类名或自定义的`@Component`注解上的`@Qualifier`值是唯一的。 总之,理解并遵循Spring Bean的命名规则和注入机制是防止这类故障的关键。在实际开发中,保持良好的命名习惯,合理使用注解和...

    spring-boot自定义starter的源码示例

    总的来说,自定义Spring Boot Starter能够帮助你构建可重用、模块化的组件,降低复杂性,并提高开发效率。通过深入学习和实践`demo-spring-boot-starter`的源码,你将更好地理解Spring Boot的自动配置原理,以及如何...

    spring-扩展点-namespacehandler(Spring自定义标签)

    在Spring框架中,扩展点是允许用户自定义行为的关键组件,而`NamespaceHandler`就是其中的一个重要扩展点,主要用于处理自定义的XML命名空间。当我们需要在Spring配置文件中引入自定义标签时,`NamespaceHandler`起...

    spring mvc 3 国际化(下)——简单自定义操作

    在“spring mvc 3 国际化(下)——简单自定义操作”这一主题中,我们将深入探讨如何自定义国际化过程,以满足特定的应用场景需求。 首先,国际化的核心是资源文件,通常命名为`messages.properties`,用于存储默认...

    spring 自定义xsd

    Spring框架是Java开发中广泛应用的...不过,需要注意的是,随着Spring的发展,Java配置和注解方式已经越来越流行,自定义XSD在某些场景下可能不再是首选,但了解这个过程仍然对理解Spring的底层工作机制有极大的帮助。

    基于注解和Spring的多数据源配置和使用

    3. **使用`@Configuration`和`@Bean`注解**:在Spring配置类中,使用`@Configuration`注解标记该类为配置类,然后使用`@Bean`注解声明数据源对象。例如: ```java @Configuration public class DataSourceConfig ...

    spring3.0依赖注入详解

    除了内置的注解,Spring还支持自定义注解,只需在自定义注解上添加`@Component`注解,即可赋予其标记Bean的能力。虽然这一特性不常用,但它展示了Spring的高度灵活性。 ##### BeanNameGenerator与自定义命名策略 ...

    Spring官方文档之核心篇

    - **Bean命名**:每个Bean都有一个或多个标识符,这些标识符在容器内必须是唯一的。可以通过id属性或name属性来指定。 - **Bean实例化**:Bean可以通过构造器、静态工厂方法或实例工厂方法来实例化。 #### 依赖 ...

    Spring2.5_注解介绍(3.0通用).pdf

    ### Spring2.5与3.0注解详解 在探讨Spring框架中注解的应用之前,我们首先需要理解注解在Java编程语言中的基础概念。注解是Java SE 5引入的一种元数据机制,用于在代码中嵌入元数据,而Spring框架充分利用了这一...

    spring boot多数据源(AOP注解动态切换)

    Spring Boot简化了传统Spring应用的配置,通过`@EnableAutoConfiguration`注解,它能自动识别并配置相应的bean。在多数据源场景下,我们需要自定义数据源配置。 1. **集成Druid连接池** Druid是一个强大的Java...

    Spring Reference - Core Technologies.pdf

    Spring允许自定义作用域,开发者可以创建自己的作用域以及在自定义作用域中使用Bean。 1.6 自定义Bean的性质 Spring允许自定义Bean的生命周期回调、依赖以及作用域等。 1.6.1 生命周期回调 Spring管理Bean的生命...

    Spring学习之(四)基于注解的组件扫描.pdf

    **组件扫描**的核心思想是:Spring会在启动时自动搜索指定包及其子包下带有特定注解的类,并将这些类作为Spring Bean注册到Spring IoC容器中。 #### 二、组件扫描的配置与使用 1. **指定扫描包路径** 在Spring的...

    springboot自定义自动装配.rar

    2. **命名规范**:自定义Starter的Maven模块名通常以`spring-boot-starter-`开头,如`spring-boot-starter-myapp`。 3. **`spring.factories`**:在Starter的`META-INF/spring.factories`文件中添加`org.spring...

Global site tag (gtag.js) - Google Analytics