zoukankan      html  css  js  c++  java
  • spring3.0使用annotation完全代替XML

    @Service与@Component有什么不同?那天被问到这个问题,一时之间却想不起来,就利用这篇文章来纪录spring3.0中常用的annotation。

    从spring2.5开始,annotation结合BeanPostProcessor成了扩展Spring IoC容器的常用方法。Spring2.5增加了对JSR-250中@Resource, @PostConstruct, @PreDestroy的支持,Spring 3.0又增加了对JSR-330 (Dependency Injection for Java)中 @Inject,@Qualifier, @Named, @Provider的支持。将相关的jsr jar包丢到classpath,并注册相应的BeanPostProcessor,其它的一切spring会帮你完成。spring还提供了一个简便的方法,通过在context的XML配置文件中加入:

    Xml代码  收藏代码
    1. <context:annotation-config/>  


    spring 会自动注册AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor,代码中就可以使用@Autowired, @Required等annotaion了。

    再回到文章开头的问题吧。spring从2.5开始加入了classpath scanning的功能,来代替之前在xml中定义Bean。首先在context的XML配置文件中加入:

    Xml代码  收藏代码
    1. <context:component-scan base-package="org.example"/>  


    spring 便会在org.example以及它的子package中查找所有的类,将符合条件的Bean注册在IoC容器当中。到3.0,spring引入了4种原型annotation(stereotype annotaion),分别为@Component, @Serivce, @Controller, @Repository。一般情况下只在将类加上@Componet,spring在扫描classpath的时候会自动检测到,并将这个类注册到IoC 容器中,在代码的其它部分,便可以借助@Autowired来注入这个Bean。后面的三种原型分别是特殊的@Conponet,适用于更加特殊的场合,比如Service层,Spring MVC, DAO等。这一点从源码上也可以看出:

    Java代码  收藏代码
    1. @Target({ElementType.TYPE})  
    2. @Retention(RetentionPolicy.RUNTIME)  
    3. @Documented  
    4. @Component  
    5. public @interface Service {  
    6.     String value() default "";  
    7. }  



    @Service本身就是被@Componet这个元注解(meta annotaion)标注的。因此对于这三个层的Bean, spring的文档也推荐将它们标注为@Service, @Controller与@Repository,因为这样更方便其它工具对这些特殊Bean的处理以及为它们加上相关AOP的 aspects,spring在后续版本的升级上也可能对它们增加更多的特殊语义。至于它们到底比普通的@Componet多了哪些 aspects,spring的文档上并没有详细说明,只简单地提到了对于@Repository,spring会自动加上exception translation,用于转化持久层抛出的异常。我google了一下,包括spring论坛的帖子,也没能找到这方面的详细信息,这点希望熟悉spring源代码的朋友能够说说。

    现在通过classpath scanning以及@Component,@Autowired等annotation,我们已无须通过xml来定义Bean了。但还必须在application context的xml中添加<context:annotation-config/>与<context:component-scan base-package="org.example"/>。再进一步想,能不能把这个配置文件也去掉,实现真正的零配置?spring3.0原先Spring JavaConfig项目的功能移到了Spring Core里面,从而实现了利用Java代码来代替传统的XML配置文件,这个功能是通过@Configuration, @Bean, @Import, @DependsOn等annotation实现的。

    Java代码  收藏代码
    1. @Configuration  
    2. public class AppConfig {  
    3.     @Bean  
    4.     public GreetingDao greetingDao() {  
    5.         return new GreetingDao();  
    6.     }  
    7. }  
    8.   
    9. public class GreetingDao {  
    10.     public String getGreeting(){  
    11.         return "Hi";  
    12.     }  
    13. }  



    @configuration表明这个类包含Bean的定义,@Bean在这里就相当于原先的配置:<bean id="greetingDao" class="septem.demo.GreetingDao"/>。通过AnnotationConfigApplicationContext就可以使用这个Bean了:

    Java代码  收藏代码
    1. @Test  
    2.     public void test_java_config(){  
    3.         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);  
    4.         GreetingDao dao = ctx.getBean(GreetingDao.class);  
    5.         assertEquals("Hi", dao.getGreeting());  
    6.     }  



    注意AppConfig里面的greetingDao虽然是是直接new出来的,但它的默认scope仍是singleton,跟采用配置文件的情况是一样的,如果需要prototype,则可以另外为它加上@Scope("prototype")。上面采用的方法是手工将Bean定义在 @Configuration里面,我们同样可以让spring自动检测Bean,比如下面的GreetingSerivce:

    Java代码  收藏代码
    1. @Service  
    2. public class GreetingService {  
    3.     public String sayHello(){  
    4.         return "Hello";  
    5.     }  
    6. }  



    将GreetingService标注为@Service,就不需要在AppConfig里面注册了:

    Java代码  收藏代码
    1. @Test   
    2.     public void test_service(){  
    3.         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();  
    4.         ctx.scan("septem.demo");  
    5.         ctx.refresh();  
    6.   
    7.         GreetingService service = ctx.getBean(GreetingService.class);  
    8.         assertEquals("Hello", service.sayHello());  
    9.     }  



    以上的ctx.scan("septem.demo")就相当于配置文件:<context:component-scan base-package="septem.demo"/>。注意因为@Configuration本身也是被@Component这个meta-annotation标注的,所以AppConfig也不需要手工在 AnnotationConfigApplicationContext里注册,它同@Service一样会被自动检测到。Spring3.0还提供了 AnnotationConfigWebApplicationContext用来代替原先web项目中的 XmlWebApplicationContext,这样在web项目中同样可以实现真正的零配置了。Spring的官方文档还提供了针对更复杂情况的处理方法,有兴趣的朋友可以看看。

  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/hyl8218/p/6128152.html
Copyright © 2011-2022 走看看