spring3 混合使用 XML 与注解(Annotation)进行 Bean 的配置

来源:互联网 发布:成都网络车新规 编辑:程序博客网 时间:2024/06/08 06:29

spring3 混合使用 XML 与注解(Annotation)进行 Bean 的配置

Posted on 2012-02-14 11:18 阳光VIP 阅读(423) 评论(0) 编辑 收藏

设计 @Configuration 和 @Bean 的初衷,并不是为了完全取代 XML,而是为了在 XML 之外多一种可行的选择。由于 Spring 自发布以来,Spring 开发小组便不断简化 XML 配置,使得 XML 配置方式已经非常成熟,加上 Spring 2.0 以后出现了一系列命名空间的支持,使得 XML 配置方式成为了使用简单、功能强大的 Bean 定义方式。而且,XML 配置的一些高级功能目前还没有相关注解能够直接支持。因此,在目前的多数项目中,要么使用纯粹的 XML 配置方式进行 Bean 的配置,要么使用以注解为主,XML 为辅的配置方式进行 Bean 的配置。

之所以会出现两者共存的情况,主要归结为三个原因:其一,目前绝大多数采用 Spring 进行开发的项目,几乎都是基于 XML 配置方式的,Spring 在引入注解的同时,必须保证注解能够与 XML 和谐共存,这是前提;其二,由于注解引入较晚,因此功能也没有发展多年的 XML 强大,因此,对于复杂的配置,注解还很难独当一面,在一段时间内仍然需要 XML 的配合才能解决问题。除此之外,Spring 的 Bean 的配置方式与 Spring 核心模块之间是解耦的,因此,改变配置方式对 Spring 的框架自身是透明的。Spring 可以通过使用 Bean 后处理器 (BeanPostProcessor) 非常方便的增加对于注解的支持。这在技术实现上非常容易的事情。

要使用混合配置方式,首先需要判断以哪一种配置方式为主。对这个问题的不同回答将会直接影响到实现的方式。然而大可不必为此伤脑筋,因为不论是以 XML 为主,还是以注解为主,配置方式都是简单而且容易理解的。这里不存在错误的决定,因为仅仅是表现方式不一样。我们首先假设以 XML 配置为主的情况。

对于已经存在的大型项目,可能初期是以 XML 进行 Bean 配置的,后续逐渐加入了注解的支持,这时我们只需在 XML 配置文件中将被 @Configuration 标注的类定义为普通的 <bean>,同时注册处理注解的 Bean 后处理器即可。示例如下:

 // 假设存在如下的 @Configuration 类: package bookstore.config;  import bookstore.dao.*;  @Configuration  public class MyConfig{  @Bean     public UserDao userDao(){         return new UserDaoImpl();     }  } 此时,只需在 XML 中作如下声明即可: <beans … >     ……    <context:annotation-config />     <bean class=”demo.config.MyConfig”/>  </beans> 

 

由于启用了针对注解的 Bean 后处理器,因此在 ApplicationContext 解析到 MyConfig 类时,会发现该类标注了 @Configuration 注解,随后便会处理该类中标注 @Bean 的方法,将这些方法的返回值注册为容器总的 Bean。

对于以上的方式,如果存在多个标注了 @Configuration 的类,则需要在 XML 文件中逐一列出。另一种方式是使用前面提到的自动扫描功能,配置如下:

 <context:component-scan base-package=”bookstore.config” /> 

 

如此,Spring 将扫描所有 demo.config 包及其子包中的类,识别所有标记了 @Component、@Controller、@Service、@Repository 注解的类,由于 @Configuration 注解本身也用 @Component 标注了,Spring 将能够识别出 @Configuration 标注类并正确解析之。

对于以注解为中心的配置方式,只需使用 @ImportResource 注解引入存在的 XML 即可,如下所示:

 @Configuration  @ImportResource(“classpath:/bookstore/config/spring-beans.xml”)  public class MyConfig{ …… }  // 容器的初始化过程和纯粹的以配置为中心的方式一致: AnnotationConfigApplicationContext ctx =               new AnnotationConfigApplicationContext(MyConfig.class); ……

 

 

@Configuration的使用

Java代码  
  1. AppConfig.javapackage com.web.spring.other;   
  2.   
  3. import org.springframework.beans.factory.annotation.Value;   
  4. import org.springframework.context.annotation.Bean;   
  5. import org.springframework.context.annotation.Configuration;   
  6. import org.springframework.context.annotation.ImportResource;   
  7.   
  8. @Configuration  
  9. @ImportResource("classpath*:spring/spring-properties.xml")   
  10. public class AppConfig {   
  11.     private @Value("${jdbc.driverClassName}") String driverClassName;   
  12.     @Bean(initMethod = "init")   
  13.     public JDBCBean jdbc(){   
  14.         JDBCBean jdbc=new JDBCBean();   
  15.         jdbc.setDriverClassName(driverClassName);   
  16.         return jdbc;   
  17.     }   
  18.   
  19. }  
AppConfig.javapackage com.web.spring.other;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.ImportResource;@Configuration@ImportResource("classpath*:spring/spring-properties.xml")public class AppConfig {    private @Value("${jdbc.driverClassName}") String driverClassName;    @Bean(initMethod = "init")    public JDBCBean jdbc(){        JDBCBean jdbc=new JDBCBean();        jdbc.setDriverClassName(driverClassName);        return jdbc;    }}

 

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" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans      
  5.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
  6.             http://www.springframework.org/schema/context     
  7.             http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  8.     <context:annotation-config/>  
  9.     <!-- picks up and registers AppConfig as a bean definition -->  
  10.     <context:component-scan base-package="com.web.spring.other" />  
  11.     <context:property-placeholder location="classpath:jdbc.properties" />  
  12.     <bean class="com.web.spring.other.AppConfig"/>  
  13. </beans>  
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd              http://www.springframework.org/schema/context              http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <context:annotation-config/>    <!-- picks up and registers AppConfig as a bean definition -->    <context:component-scan base-package="com.web.spring.other" />    <context:property-placeholder location="classpath:jdbc.properties" />    <bean class="com.web.spring.other.AppConfig"/></beans>

 

使用@Configuration注解需要依赖CGLIB的JAR包
否则异常

Java代码  
  1. Exception in thread "main" java.lang.IllegalStateException: CGLIB is required to process @Configuration classes.    
  2. Either add CGLIB to the classpath or remove the following @Configuration bean definitions: [spring3HelloWorldConfig]   
  3.   
  4. at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:257)   
  5.   
  6. at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:147)   
  7.   
  8. at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:624)   
  9.   
  10. at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:614)   
  11.   
  12. at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:398)   
  13.   
  14. at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:65)   
  15.   
  16. at net.roseindia.Spring3HelloWorldConfigTest.main(Spring3HelloWorldConfigTest.java:9)  
原创粉丝点击