基于Java配置选项,可以编写大多数的spring不用配置XML,但有几个基于Java的注释的帮助下解释。从Spring3.0开始支持使用java代码来代替XML来配置Spring,基于Java配置Spring依靠Spring的JavaConfig项目提供的很多优点。通过使用@Configuration, @Bean ,@Importand,@DependsOnannotations来实现Java的配置Spring. 本文工程下载
@Configuration & @Bean 注解:
在Spring的新的Java-Configuration的中间产物是基于类的@Configuration的注解和基于方法的@Bean注解。
@Bean注解是用来指明方法的实例化,配置和初始化一个对象是通过Spring的IoC容器来管理的。对于那些熟悉使用以XML配置Spring的
@Configuration注解的类指明该类主要是作为一个bean的来源定义。此外,@Configurationd定义的classes允许在同一个类中使用@Bean定义的方法来定义依赖的bean 注释类与@Configuration表示这个类可以使用Spring IoC容器为bean定义的来源。在@Bean 注解告诉Spring的注解为@Bean的一个方法将返回应注册为在Spring应用程序上下文中的bean对象。最简单可行的@Configuration类将如下所示: [java] view plain copy 在CODE上查看代码片派生到我的代码片 @Configuration
public class CompanyConfig { @Bean
public Employee employee(){ return new Employee(); } }
上面的代码将等同于下面的XML配置:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
下面注解为@Bean的方法名称作为工作bean的id,它创建并返回实际的bean。配置类可以有声明多个@Bean。一旦配置类定义,可以加载和提供他们使用AnnotationConfigApplicationContext 如下,以Spring容器: [java] view plain copy 在CODE上查看代码片派生到我的代码片 public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(CompanyConfig.class); Employee employee=ctx.getBean(Employee.class); employee.setName(\"笨笨\"); employee.setId(2012); System.out.println(employee); } 也可以这样写: [java] view plain copy 在CODE上查看代码片派生到我的代码片 package com.mucfc.anno; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(CompanyConfig.class); ctx.refresh(); Employee employee1 = ctx.getBean(Employee.class); Employee employee2 = ctx.getBean(Employee.class); employee1.setName(\"笨笨\"); employee1.setId(2012); employee2.setName(\"狂人\"); employee2.setId(34546); System.out.println(\"exployee1\"+employee1); System.out.println(\"exployee2\"+employee2); System.out.print(\"employee1==employee2?:\"); System.out.print(employee1==employee2); } } 把上面的@Bean加个@scope [java] view plain copy 在CODE上查看代码片派生到我的代码片 package com.mucfc.anno; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration public class CompanyConfig { @Bean @Scope(\"singleton\") public Employee employee(){ return new Employee(); } } 其它不变。运行结果: 说明默认返回的是singleton类型,这里改成了prototpye 这么做有什么好处呢? 1.使用纯java代码,不在需要xml 2.在配置中也可享受OO带来的好处 3.类型安全对重构也能提供良好的支持 4.依旧能享受到所有springIoC容器提供的功能 ApplicationContext 接口的最常用的实现类是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext,以及面向 Portlet 的 XmlPortletApplicationContext 和面向 web 的 XmlWebApplicationContext,它们都是面向 XML 的。Spring 3.0 新增了另外两个实现类:AnnotationConfigApplicationContext 和 AnnotationConfigWebApplicationContext。从名字便可以看出,它们是为注解而生,直接依赖于注解作为容器配置信息来 源的 IoC 容器初始化类。由于 AnnotationConfigWebApplicationContext 是 AnnotationConfigApplicationContext 的 web 版本,其用法与后者相比几乎没有什么差别,因此本文将以 AnnotationConfigApplicationContext 为例进行讲解。 AnnotationConfigApplicationContext 搭配上 @Configuration 和 @Bean 注解,自此,XML 配置方式不再是 Spring IoC 容器的唯一配置方式。两者在一定范围内存在着竞争的关系,但是它们在大多数情况下还是相互协作的关系,两者的结合使得 Spring IoC 容器的配置更简单,更强大。之前,我们将配置信息集中写在 XML 中,如今使用注解,配置信息的载体由 XML 文件转移到了 Java 类中。我们通常将用于存放配置信息的类的类名以 “Config” 结尾,比如 AppDaoConfig.java、AppServiceConfig.java 等等。我们需要在用于指定配置信息的类上加上 @Configuration 注解,以明确指出该类是 Bean 配置的信息源。 注意:Spring 对标注 Configuration 的类有如下要求 配置类不能是 final 的;配置类不能是本地化的,亦即不能将配置类定义在其他类的方法内部;配置类必须有一个无参构造函数。AnnotationConfigApplicationContext 将配置类中标注了 @Bean 的方法的返回值识别为 Spring Bean,并注册到容器中,受 IoC 容器管理。@Bean 的作用等价于 XML 配置中的 标签。 @Bean 具有以下四个属性: name -- 指定一个或者多个 Bean 的名字。这等价于 XML 配置中 的 name 属性。 initMethod -- 容器在初始化完 Bean 之后,会调用该属性指定的方法。这等价于 XML 配置中 的 init-method 属性。 destroyMethod -- 该属性与 initMethod 功能相似,在容器销毁 Bean 之前,会调用该属性指定的方法。这等价于 XML 配置中 的 destroy-method 属性。 autowire -- 指定 Bean 属性的自动装配策略,取值是 Autowire 类型的三个静态属性。Autowire.BY_NAME,Autowire.BY_TYPE,Autowire.NO。与 XML 配置中的 autowire 属性的 取值相比,这里少了 constructor,这是因为 constructor 在这里已经没有意义了。@Bean 没有直接提供指定作用域的属性,可以通过 @Scope 来实现该功能。 由于@configureation注解类本身已经标注了@component注解,所以任何标注了@configuration的类,本身也相当于标注了@component,即它们可以像普通的bean一样被注入到其它bean中去。 如下面: [java] view plain copy 在CODE上查看代码片派生到我的代码片 package com.mucfc.anno; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @Configuration public class Company { @Autowired //自动装配Configuration定义好的 CompanyConfig private CompanyConfig companyConfig; public CompanyConfig getCompanyConfig() { return companyConfig; } public void setCompanyConfig(CompanyConfig companyConfig) { this.companyConfig = companyConfig; } } 使用: [java] view plain copy 在CODE上查看代码片派生到我的代码片 ctx.register(CompanyConfig.class); ctx.register(Company.class); ctx.refresh(); [java] view plain copy 在CODE上查看代码片派生到我的代码片 Employee employee3 = ctx.getBean(Company.class).getCompanyConfig().employee(); employee3.setName(\"红色革命\"); employee3.setId(2342); System.out.println(\"exployee3\"+employee3); 输出结果: exployee3员工姓名:红色革命 员工编号 :2342 使用基于java类的配置信息启动Spring容器: [java] view plain copy 在CODE上查看代码片派生到我的代码片 /* AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(CompanyConfig.class); ctx.register(Company.class); ctx.refresh(); */ ApplicationContext ctx=new AnnotationConfigApplicationContext(CompanyConfig.class); 其中注释的代码和不注释的代码可以看成是相同的,运行后结果不 @Import 注解: @ import的注解允许加载@Bean从另一个配置类定义。考虑一个配置类,如下所示: [java] view plain copy 在CODE上查看代码片派生到我的代码片 @Configuration public class ConfigA { @Bean public A a() { return new A(); } } 您可以在另一个bean声明导入上述bean声明如下 [java] view plain copy 在CODE上查看代码片派生到我的代码片 @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public B a() { return new A(); } } 现在,不需要实例化的前提下,当同时指定配置A.class和配置B.class,只有Config B类需要如下提供: [java] view plain copy 在CODE上查看代码片派生到我的代码片 public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class); // now www.baiyuewang.netboth beans A and B will be available... A a = ctx.getBean(A.class); B b = ctx.getBean(B.class); } 生命周期回调: @Bean注解支持指定任意的初始化和销毁回调方法,就像Spring的XML的初始化方法和bean元素销毁方法的属性: [java] view plain copy 在CODE上查看代码片派生到我的代码片 public class Foo { public void init() { // initialization logic } public void cleanup() { // destruction logic } } @Configuration public class AppConfig { @Bean(initMethod = \"init\ public Foo foo() { return new Foo(); } } 指定Bean的适用范围: 默认范围是单例,但可以使用@Scope注解来覆盖此如下: [java] view plain copy 在CODE上查看代码片派生到我的代码片 @Configuration public class AppConfig { @Bean @Scope(\"prototype\") public Foo foo() { return new Foo(); } } 三种配置bean方式的对比总结 因篇幅问题不能全部显示,请点此查看更多更全内容