`
zhongzhihua
  • 浏览: 311174 次
  • 来自: ...
社区版块
存档分类
最新评论

备忘-使用annotation减少spring bean的配置

阅读更多
备忘-使用annotation减少spring bean的配置  收藏
发现一篇好文 http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/ 它给出了比本文更详细的说明。

springframework 2.5引入了完整的annotaion配置注解,使用这些annotation可以大量的减少bean的定义,也使得程序开发更简单和容易维护。

当然你要使用annotation就需要使用java5以上版本。

使用annotaion定义一个bean
@Component是一个通用注解,用于说明一个类是一个spring容器管理的类。
除此之外,还有@Controller, @Service, @Repository是@Component的细化,这三个注解比@Component带有更多的语义,它们分别对应了表现层、服务层、持久层的类。
如果你只是用它们定义bean,你可以仅使用@Component,但是既然spring提供这些细化的注解,那肯定有使用它们的好处,不过在以下的例子中体现不出。

定义了一个接口

   1. package test1;
   2.
   3. interface MovieFinder {
   4.     String getData();
   5. }

定义一个实现

   1. package test1;
   2.
   3. import org.springframework.stereotype.Repository;
   4.
   5. @Repository
   6. public class JpaMovieFinder implements MovieFinder {
   7.
   8.     @Override
   9.     public String getData() {
  10.         return "This is JpaMovieFinder implementation!";
  11.     }
  12.
  13. }

这里使用了注解@Repository,说明这是一个受spring容器管理的bean定义,这个注解没有指定bean的名字,默认为小写开头的类名,就是jpaMovieFinder,如果你要指定名字,可以这样写@Repository("myMovieFinder")。
这里也可以使用@Component这个注解,在这里例子中体现不出用@Repository的好处。
这里没有指定这个bean的scope,缺省是singleton,如果你要其他scope,可以使用注解@Scope

   1. @Scope("prototype")
   2. @Repository
   3. public class MovieFinderImpl implements MovieFinder {
   4.     // ...
   5. }


spring扫描并注册注解的bean
JpaMovieFinder只是添加了一个注解,这并不会自动被注册到spring容器中,我们需要告诉spring容器到那里去寻找这些bean。
配置如下:

   1. <?xml version="1.0" encoding="UTF-8"?>
   2. <beans xmlns="http://www.springframework.org/schema/beans"
   3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   4.        xmlns:context="http://www.springframework.org/schema/context"
   5.        xsi:schemaLocation="http://www.springframework.org/schema/beans
   6.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
   7.            http://www.springframework.org/schema/context
   8.            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
   9.               
  10.      <context:component-scan base-package="test1"/>
  11.     
  12. </beans>

<context:component-scan base-package="test1"/>这个配置告诉spring容器到test1这个package下去扫描所有的类,从而找到被注解的类。
由于并不是test1下的所有的类都有注解,全部遍历效率不高,所以spring定义了过滤器用于减小扫描范围,这里为了简单起见没有使用。

使用注解进行依赖注入

   1. package test1;
   2.

   3. import org.springframework.beans.factory.annotation.Autowired;
   4. import org.springframework.stereotype.Service;
   5.

   6. @Service
   7. public class SimpleMovieLister {
   8.    
   9.     @Autowired
  10.     private MovieFinder movieFinder;
  11.

  12.     public String getData(String name) {
  13.         return "Hi " + name + "! " + movieFinder.getData();
  14.     }
  15.    
  16.     public MovieFinder getMovieFinder() {
  17.         return movieFinder;
  18.     }
  19.

  20.     public void setMovieFinder(MovieFinder movieFinder) {
  21.         this.movieFinder = movieFinder;
  22.     }
  23. }

SimpleMovieLister是一个服务类,它也使用了@Service注解为了bean,这个类用到了MovieFinder,为了注入这个类的实现,这里使用了注解@Autowired,spring容器会自动找到合适的bean注入进去。注意这里并没有指定被注入bean的名字,因为spring根据只发现了一个实现,那就是jpaMovieFinder。后面,我们会看到有两个实现会怎样。

注意,上面代码使用@Autowired时,public void setMovieFinder(MovieFinder movieFinder) 这个方法是不需要的,你可以把它删除了试一试。如果你使用xml的配置方式,该方法必须存在。我这里保留该方法,是为了后面测试注解和xml配置混合使用的方式。

测试1

   1. package test1;
   2.

   3. import org.springframework.context.ApplicationContext;
   4. import org.springframework.context.support.ClassPathXmlApplicationContext;
   5.

   6. public class Main {
   7.

   8.     public static void main(String[] args) {
   9.         ApplicationContext context = new ClassPathXmlApplicationContext("test1/beans.xml");
  10.         SimpleMovieLister m = (SimpleMovieLister)context.getBean("simpleMovieLister");
  11.         System.out.println(m.getData("Arthur"));
  12.     }
  13.

  14. }
  15.

控制台上会打印 Hi Arthur! This is JpaMovieFinder implementation!

增加MovieFinder的第二个实现

   1. package test1;
   2.
   3. import org.springframework.stereotype.Repository;
   4.
   5. @Repository
   6. public class IbatisMovieFinder implements MovieFinder {
   7.
   8.     @Override
   9.     public String getData() {
  10.         return "This is IbatisMovieFinder implementation!";
  11.     }
  12.
  13. }
14.


这时运行Main,系统会报错:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMovieLister': Injection of resource fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [test1.MovieFinder] is defined: expected single matching bean but found 2: [jpaMovieFinder, ibatisMovieFinder]
从错误信息中我们可以看到现在MovieFinder有两个bean实现了,一个是jpaMovieFinder,另一个是ibatisMovieFinder,spring容器不知道应该使用哪一个bean。这时可以使用注解@Qualifier指定具体的bean。

   1. //...
   2. @Service
   3. public class SimpleMovieLister {
   4.

   5.     @Autowired
   6.     @Qualifier("ibatisMovieFinder")
   7.     private MovieFinder movieFinder;
   8. //...

这里我们指定注入的是ibatisMovieFinder这个bean。
运行Main, 控制台上会打印 Hi Arthur! This is IbatisMovieFinder implementation!

Java6提供的注入注解
spring也可以使用java6提供的@Resource注解来指定注入哪一个bean。

   1. //...
   2. @Service
   3. public class SimpleMovieLister {
   4.
   5.     @Resource(name="ibatisMovieFinder")
   6.     private MovieFinder movieFinder;
   7. //...

这和@Autowired功能是一致的。

使用注解还是xml
使用注解很方便,但从上面的例子我们也可以看出注解的问题,MovieFinder有两个实现,SimpleMovieLister是在程序中用注解指定了使用哪一个实现,如果要修改,需要修改源程序。所以,注解只适用于固定依赖的情况。如果依赖需要在部署的时候做调整,那还是使用xml的配置方式方便,毕竟只需要修改一下xml文件即可。

实际使用时,我们可以xml和注解两种方式混合使用。

   1. <?xml version="1.0" encoding="UTF-8"?>
   2. <beans xmlns="http://www.springframework.org/schema/beans"
   3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   4.        xmlns:context="http://www.springframework.org/schema/context"
   5.        xsi:schemaLocation="http://www.springframework.org/schema/beans
   6.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
   7.            http://www.springframework.org/schema/context
   8.            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
   9.               
  10.     <context:component-scan base-package="test1"/>
  11.    
  12.     <bean id="simpleMovieLister1" class="test1.SimpleMovieLister">
  13.         <property name="movieFinder" ref="jpaMovieFinder" />
  14.     </bean>
  15.    
  16. </beans>

使用xml配置方式定义了另外一bean,注入了jpaMovieFinder这个实现。

   1. package test1;
   2.

   3. import org.springframework.context.ApplicationContext;
   4. import org.springframework.context.support.ClassPathXmlApplicationContext;
   5.

   6. public class Main {
   7.

   8.     public static void main(String[] args) {
   9.         ApplicationContext context = new ClassPathXmlApplicationContext("test1/beans.xml");
  10.         SimpleMovieLister m = (SimpleMovieLister)context.getBean("simpleMovieLister");
  11.         System.out.println(m.getData("Arthur"));
  12.         SimpleMovieLister m1 = (SimpleMovieLister)context.getBean("simpleMovieLister1");
  13.         System.out.println(m1.getData("Arthur"));
  14.     }
  15.

  16. }

simpleMovieLister是从注解来的,simpleMovieLister1是从xml配置来的。运行结果:
Hi Arthur! This is IbatisMovieFinder implementation!
Hi Arthur! This is JpaMovieFinder implementation!

证明混合使用是可行的,你可以继续测试,用xml重新配置simpleMovieLister。
因此,即使我一开始使用了注解,之后我后悔了,没有关系,不用修改源程序,以前用xml怎么配置现在还是怎么配置。
分享到:
评论

相关推荐

    point-cloud-annotation-tool win10解压直接运行

    通过了解和熟练使用"point-cloud-annotation-tool",你将能够有效地对点云数据进行标注,为后续的分析和建模提供高质量的数据基础。随着点云技术的发展,掌握这类工具的使用将对你的IT事业大有裨益。

    Spring学习笔记(18)----使用Spring配置文件实现事务管理

    5. **事务的配置**: 在Spring的XML配置文件中,我们需要定义`&lt;tx:annotation-driven&gt;`标签来启用基于注解的事务管理,并指定事务管理器。事务管理器通常是`PlatformTransactionManager`接口的实现,如`...

    Spring学习笔记(16)----使用Spring配置文件实现AOP

    在本篇Spring学习笔记中,我们将深入探讨如何利用Spring配置文件来实现面向切面编程(AOP)。面向切面编程是Spring框架的核心特性之一,它允许我们把关注点分离,将横切关注点(如日志、事务管理、权限控制等)与...

    point-cloud-annotation-tool

    github链接链接:https://github.com/springzfx/point-cloud-annotation-tool 在windows平台编译完成后的exe和dll文件,可以直接打开使用,并对原项目进行了优化,增加了列表和标注文件的显示功能,标注起来更快,...

    spring-security-helloworld-annotation

    本文将深入探讨一个名为"spring-security-helloworld-annotation"的示例,该示例展示了如何使用注解来配置Spring Security。我们将从基本概念、核心组件到实际应用,全面解析Spring Security的注解使用。 1. **注解...

    使用Spring的声明式事务----Annotation注解方式

    &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt; ``` 这里`transactionManager`是我们的事务管理器,通常是一个`PlatformTransactionManager`的实现,如`DataSourceTransactionManager`。 ...

    mybatis-plus-annotation-3.2.0-API文档-中英对照版.zip

    赠送jar包:mybatis-plus-annotation-3.2.0.jar; 赠送原API文档:mybatis-plus-annotation-3.2.0-javadoc.jar; 赠送源代码:mybatis-plus-annotation-3.2.0-sources.jar; 赠送Maven依赖信息文件:mybatis-plus-...

    mybatis-plus-annotation-3.5.3.2.jar

    mybatis-plus-annotation.jar MP 注解 jar 包 mybatis-plus 的注解 jar 包,包含了 mybatis-plus 注解功能 各个版本

    Spring annotation

    Spring注解的使用大大减少了XML配置,提高了代码的可读性和维护性。理解并熟练运用这些注解是每个Spring开发者必备的技能。在实际开发中,根据项目需求选择合适的注解,可以有效地组织和管理代码,提升开发效率。

    Spring boot 示例 官方 Demo

    spring-boot-mybatis-annotation-mulidatasource:springboot+mybatis(注解版)多数据源最简解决方案 spring-boot-thymeleaf:simple spring boot thymeleaf demo spring-boot-jpa-thymeleaf-curd:spring boot + ...

    mybatis-plus-annotation-3.4.0.jar

    mybatis-plus-annotation-3.4.0.jar

    spring[1]-使用ImportBeanDefinitionRegistrar自定义注册bean(基于源码).zip

    这个接口主要用于扩展Spring配置,使得我们可以在不编写XML配置或使用`@Configuration`注解类的情况下,根据某些条件动态地注册bean。下面将详细探讨`ImportBeanDefinitionRegistrar`的工作原理、使用场景以及如何...

    geronimo-annotation_1.0_spec-1.1.1-API文档-中文版.zip

    赠送jar包:geronimo-annotation_1.0_spec-1.1.1.jar; 赠送原API文档:geronimo-annotation_1.0_spec-1.1.1-javadoc.jar; 赠送源代码:geronimo-annotation_1.0_spec-1.1.1-sources.jar; 赠送Maven依赖信息文件:...

    mybatis-plus-annotation-3.5.1-API文档-中文版.zip

    赠送jar包:mybatis-plus-annotation-3.5.1.jar; 赠送原API文档:mybatis-plus-annotation-3.5.1-javadoc.jar; 赠送源代码:mybatis-plus-annotation-3.5.1-sources.jar; 赠送Maven依赖信息文件:mybatis-plus-...

    spring的annotation-driven配置事务管理器详解 (多数据源配置

    Spring 框架提供了强大的事务管理机制,通过使用 Annotation-Driven 配置,可以方便地管理事务。在多数据源配置中,spring 的 Annotation-Driven 配置事务管理器可以帮助我们轻松地管理多个数据源的事务。 在 ...

    mybatis-plus-annotation-3.1.0-API文档-中文版.zip

    赠送jar包:mybatis-plus-annotation-3.1.0.jar; 赠送原API文档:mybatis-plus-annotation-3.1.0-javadoc.jar; 赠送源代码:mybatis-plus-annotation-3.1.0-sources.jar; 赠送Maven依赖信息文件:mybatis-plus-...

    前端项目-chartjs-plugin-annotation.zip

    **Chart.js插件-Annotation详解** 在前端开发中,数据可视化是至关重要的,它能够将复杂的数据以图形的形式展示,使用户更容易理解。Chart.js是一个轻量级且强大的JavaScript库,用于创建各种图表,如折线图、柱状...

    mybatis-plus-annotation-3.5.1-API文档-中英对照版.zip

    赠送jar包:mybatis-plus-annotation-3.5.1.jar; 赠送原API文档:mybatis-plus-annotation-3.5.1-javadoc.jar; 赠送源代码:mybatis-plus-annotation-3.5.1-sources.jar; 赠送Maven依赖信息文件:mybatis-plus-...

    Spring Boot Examples

    spring-boot-mybatis-annotation-mulidatasource:springboot+mybatis(注解版)多数据源最简解决方案 spring-boot-thymeleaf:simple spring boot thymeleaf demo spring-boot-jpa-thymeleaf-curd:spring boot +...

    mybatis-plus-annotation-3.1.0-API文档-中英对照版.zip

    赠送jar包:mybatis-plus-annotation-3.1.0.jar; 赠送原API文档:mybatis-plus-annotation-3.1.0-javadoc.jar; 赠送源代码:mybatis-plus-annotation-3.1.0-sources.jar; 赠送Maven依赖信息文件:mybatis-plus-...

Global site tag (gtag.js) - Google Analytics