技术开发 频道

Spring的新配置选项


IT168评论】 
    在最近的Blog中,Rod Johnson介绍了Spring应用程序的一个新的配置选项,这个新的配置选项并不是打算来取代Spring的基于XML的配置.新的选项在Java类中定义了配置,这个配置Rod Johnson描述为一个小的配置DSL. 

    值得提到的一点就是,人们经常忽略Spring配置不需要在XML文件中,虽然XML的形式是目前最通用的使用形式.Spring在BeanDefinition接口和子接口的形式上有自己的内部的元数据形式. 代表IOC容器实例的BeanFactory 和ApplicationContext的实现被这种Java元数据赋有强大的动力.并且从元数据的解析中各自分离,这通常是由BeanDefinitionReader实现来执行的. 

    BeanDefinition最初并不是按开发者的观点来设计的,Spring2.0, NamespaceHandlers(处理XML扩展命名空间的类)产生BeanDefinition元数据,我们引进BeanDefinition,用方便的API使得这更加容易.但是产生BeanDefinition元数据只不过留在架构代码的领域,而不是像你每天写业务逻辑代码和定义规则的Spring bean所做的那样. 

    今天,我想要描述一个新的选项来在Java代码中定义beans,当前是Spring core增加的扩展功能.

    首先来看一个例子:

@Configuration public class MyConfig { @Bean public Person rod() { return new Person("Rod Johnson"); } @Bean(scope = Scope.PROTOTYPE) public Book book() { Book book = new Book("Expert One-on-One J2EE Design and Development"); book.setAuthor(rod()); // rod() method is actually a bean reference ! return book; } }
    @Configuration注释标识这个对象作为一个特殊配置类,每一个@Bean方法定义了一个bean.bean的名字是方法的名字,它也可以用注释来定义而外的名字.但是最好从方法中选择名字,而不是注释中,这就像编译器能够确保其唯一性一样. 

    Beans在Java代码中配置,使用构造器,属性或者任意的方法调用,我们注意到调用另外一个bean方法建立了一个从”book” bean到”rod” bean的依赖.但是在Java的实例对象中没有框架的支持有一个主要的优点:例如: 
    每个@Bean是Spring组件并能利用所有的Spring服务,例如声明事务管理. 
    每个public @Bean方法被增加到Spring容器中,因此注入到其他对象,JMX导出和其他定义中是可以的. 
    在现存的Spring环境中是适合的. 

    通过比较XML定义来完成同样的结果是更容易的,就象下面这样:
<bean id="rod" class="Person" scope="singleton"> <constructor-arg>Rod Johnson</constructor-arg> </bean> <bean id="book" class="Book" scope="prototype"> <constructor-arg>Expert One-on-One J2EE Design and Development</constructor-arg> <property name="author" ref="rod"/> </bean>
    虽然这是基于Java注释的,Java配置机制在注释的使用上是唯一的,注释并没有包含在核心的业务逻辑中,而是在每个独立的配置类中.对配置来说,这是DSL,因此,它保留了Spring的非侵入允诺.,你可以不必改变Java代码来使用. 

    这个配置类,类似与一个XML bean定义文件,并且这样的@Configuration注释包含一些对<bean>元素相似的选项,像默认的延迟初始化,例如:
@Configuration(defaultAutowire = Autowire.BY_TYPE, defaultLazy = Lazy.FALSE) public class DataSourceConfiguration extends ConfigurationSupport { }
    @Bean注释允许像范围,延迟初始化选项在本地设置,正如<bean>元素,默认的范围是Singleton.

@Configuration注释标识这个对象作为一个特殊配置类,每一个@Bean方法定义了一个bean.bean的名字是方法的名字,它也可以用注释来定义而外的名字.但是最好从方法中选择名字,而不是注释中,这就像编译器能够确保其唯一性一样. Beans在Java代码中配置,使用构造器,属性或者任意的方法调用,我们注意到调用另外一个bean方法建立了一个从”book” bean到”rod” bean的依赖.但是在Java的实例对象中没有框架的支持有一个主要的优点:例如: 每个@Bean是Spring组件并能利用所有的Spring服务,例如声明事务管理. 每个public @Bean方法被增加到Spring容器中,因此注入到其他对象,JMX导出和其他定义中是可以的. 在现存的Spring环境中是适合的. 通过比较XML定义来完成同样的结果是更容易的,就象下面这样: 虽然这是基于Java注释的,Java配置机制在注释的使用上是唯一的,注释并没有包含在核心的业务逻辑中,而是在每个独立的配置类中.对配置来说,这是DSL,因此,它保留了Spring的非侵入允诺.,你可以不必改变Java代码来使用. 这个配置类,类似与一个XML bean定义文件,并且这样的@Configuration注释包含一些对<bean>元素相似的选项,像默认的延迟初始化,例如: @Bean注释允许像范围,延迟初始化选项在本地设置,正如<bean>元素,默认的范围是Singleton.
【IT168技术文档】 
    Java配置的样式有些有意思的特点,例如:
    参考(例如在例子中”rod” bean的参考)避免重构,任何好的IDE都提供了工具支持. 

    因为配置是Java类.他们可以参与到继承关系,例如,你可以定义需要一些抽象的@Bean在超类中执行的超类. 

    创建了一个新的可视选项,@Bean方法被声明为保护类型,这中情况可以从Spring组件的一般特性中得到益处,在外部并不可见.也就是说它是不可注入的也不能通过在IOC Context中调用getBean()方法来获得. 

    作为Spring XML格式的替代品并不是有意的,像Spring 2.0扩展命名空间,自从Spring1.0属性文件的使用也成为可能.复杂的应用要求配置类型的多样化,Spring的目的在于提供对配置的更好的解决方案.我们继续探讨配置的其他形式. 

    一般我们将Java和XML配置混合使用,你可以在同样的应用上下文中使用多个Java配置类. 

    接下来的例子我们使用XML bean定义来定义MyConfig bean,就像上面说的那样能够像其他普通的bean一样可以注入. ConfigurationPostProcessor使用@Configuration注释来出来所有的beans,产生必要的bean定义.
<beans> <bean class="..MyConfig"/> <bean class="org.springframework.beans.factory.java.ConfigurationPostProcessor"/> <bean class="SomeRandomBean"> <property… </bean> </beans>
    当然,我们可以使用普通bean定义,像这个例子中的SomeRandomBean,你可以构建Java配置和现存XML配置的应用上下文.
使用通配符来从环境变量中加载类,像这样:
ApplicationContext oneConfig = new
AnnotationApplicationContext(SimpleConfiguration.
class.getName()); ApplicationContext aBunchOfConfigs = new
AnnotationApplicationContext(
"**/configuration/*Configuration.class");
    类通过使用(并不加载)ASM来检查,在将来的版本中可能会提供自动检测设定. 

    该实现并不需要对Spring Core进行任何的修改,IOC容器非常灵活,它将配置对象看作一个factory bean并且每个bean定义那个对象的一个实例工厂方法来支持.这种机制从Spring 1.1就可用,在配置实例上没有一点字节码处理,目前使用CGLIB来确保对singleton范围@Bean方法的重复调用总是返回同样的对象.
0
相关文章