杨瑞东,王云峰,张海英
(1. 中国科学院微电子研究所 新一代通信射频芯片技术北京市重点实验室,北京 100029; 2. 中国科学院大学,北京 100049)
Spring新特性之Java Config在Web开发中的应用
杨瑞东1,2,王云峰1,张海英1
(1. 中国科学院微电子研究所 新一代通信射频芯片技术北京市重点实验室,北京 100029; 2. 中国科学院大学,北京 100049)
为提高项目开发的效率,对Spring新特性Java Config在Web开发中的应用作了深入研究。以传统的使用XML配置Spring的方式为对比,对新特性Java Config的使用方法和其优势作了介绍。以实际案例的形式具体描述了Spring中XML配置方式和Java Config配置的方式。结果表明,Java Config在Web项目开发中具有操作简单、编译器错误检查、更符合程序员编程规范等优势。使用Java Config的方式还可以配合Servlet3.0完全去掉传统Web项目中固有的web.xml文件。Java Config将成为Web开发的流行趋势。
Spring;Java Config;容器;注解
Abstract: In order to improve the efficiency of project development, intensive study of the application of Spring’s new feature Java Config in Web development is made. By contrasting with the conventional way of configuring Spring with XML, the usage method and advantage of Spring’s new feature Java Config are introduced. In the form of actual cases, Spring’s XML config and Java Config are described. As a result, Java Config in Web development has some advantages such as simple operation, compiler error checking, programming specification. The way of Java Config combined with Servlet3.0 can get rid of conventional file web.xml. Java Config will be the main trend of the Web development in the future.
Key words:Spring; Java Config; container; annotation
Spring是目前Web开发中非常流行的一个容器框架,是进行对象管理、对象关联、解耦的一个中间层框架[1]。它的主要功能是创建Java bean并维护bean与bean之间的关系。在传统的使用Spring的项目中都是采用外部XML文件的方式进行配置,利用XML文件来管理bean之间的依赖关系[2]。由于XML文件和程序是分离的,而且XML文件没有集成工具语法检查,随着项目不断增大,对XML的管理就越来越复杂,特别容易出错。
Spring在新的版本中引入了使用Java Config进行配置的方式,这种配置方式使用Java类的形式来代替传统使用的XML文件,使用Java类进行配置编译器可以在编译期间检查错误,这大大提高了程序开发的效率,而且使用Java编程的方式进行Spring配置更符合程序员的编程风格。利用Java Config进行Spring项目的配置是目前使用Spring的一个新的思路,相对于使用XML进行配置,使用Java Config的方式更加简化,程序员不需要频繁地在Java代码和XML文件之间进行切换,而且也可以在一定程度上减少语法错误的可能性。
在Web项目中使用Spring框架时,不需要手动去创建Spring容器,而是通过外部配置文件声明式地创建Spring容器,可以在web.xml文件中进行Spring容器的配置[3]。
Spring容器需要随着Web应用的启动而启动,这可以利用ServletContextListener来实现。Spring为开发者提供了ServletContextListener的一个实现类ContextLoaderListener,这个类作为Listener会在创建时默认自动去查找WEB-INF/applicationContext.xml文件。所以如果Spring的配置文件只有一个而且名字命名为applicationContext.xml,只需要在web.xml中进行如下配置:
如果Spring的配置文件命名为其他的名字或者配置文件不止一个,则需要用
/WEB-INF/serviceContext.xml,/WEB-INF/actionContext.xml,/WEB-INF/daoContext.xml
在项目的web.xml文件中,如果开发者没有通过contextConfigLocation指定配置文件,则Spring会自动在类路径下查找applicationContext.xml文件,如果有contextConfigLocation,则Spring利用该参数确定配置文件;如果无法找到合适的配置文件,则Spring将无法正常初始化。
Spring初始化完成并且正常启动后,定义在Spring配置文件中的bean就会被实例化[4]。这里以单个配置文件applicationContext.xml为例来介绍在Spring容器中如何定义并初始化bean。
定义三个类,分别是Person类、Car类、Company类。Person类具有Car类和Company类的引用,类定义如下:
public class Car{
private String name;
//省略get/set方法
}
public class Company{
private String name;
//省略get/set方法
}
public class Person{
private Car car;
private Company company;
//省略get/set方法
}
要在Spring容器中初始化这三个类,需要在applicationContext.xml中进行配置。以下代码说明了上面三个类在上下文XML中bean的定义。
这样Spring容器在启动的时候,容器内就会实例化Person、Car、Company这三个类,并且三个类中的属性也会自动地注入进去。在Person类中使用属性car和company时就不用单独去创建对象,Spring已经自动进行了实例的创建,而且默认情况下Spring创建的实例都是单例的[5]。如果需要将实例修改为非单例模式,开发者可以在Spring的配置文件applicationContext.xml中进行设置。
相对传统使用XML进行配置的方式,Spring新推出了一种基于Java Config进行配置的方式[6]。在这种配置方式里丢弃了传统的Spring配置文件applicationContext.xml,甚至加上Servlet3.0的支持,连Web项目中的web.xml都可以省略。
2.1在Web项目中去掉web.xml
首先来讨论如何去掉传统Web项目中的web.xml文件。对于一个传统的Web应用,其部署在Web容器中的时候,Web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的Spring 容器提供了宿主环境。其次,在web.xml文件中会提供有contextLoaderListener。在Web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,Spring框架会初始化一个启动上下文,这个启动上下文就称为根上下文,也就是WebApplicationContext,这是一个接口类,确切地说,其实际的实现类是XmlWebApplicationContext。这个就是Spring的IoC容器,其对应的bean定义的配置文件由web.xml中的context-param标签指定。
具有Servlet3.0支持的服务器在启动一个Web项目的时候,服务器会自动在项目代码中扫描实现了WebApplicationInitializer接口的类,该类属于Spring,在WebApplicationInitializer接口中有onStartup方法,Spring会自动执行这个方法启动Web应用。下面的代码是一个实现了WebApplicationInitializer接口的类。
public class WebAppInitializer implements
WebApplicationInitializer{
@Override
public void onStartup(ServletContext container)
throws ServletException {
AnnotationConfigWebApplicationContext rootContext=new AnnotationConfigWebApplicationContext();
rootContext.register(AppContext.class);
container.addListener(new ContextLoaderListener(rootContext));
}
}
2.2 Java Config配置Spring
在传统的使用XML文件配置的方法中,使用ClassPathXmlApplicationContext 类来加载外部 XML上下文文件。但在使用基于Java Config的方法配置Spring进行开发的时候,可以使用一个基于注解配置的AnnotationConfigApplicationContext类。在2.1节的代码中,WebAppInitializer类的onStartup方法被执行时,AnnotationConfigApplicationContext实例马上被创建。AnnotationConfigApplicationContext类其实是 ApplicationContext 接口的一个实现,能够注册所注解的配置类。在下面的代码中,使用AppContext类来代替传统的XML文件作为配置类来实现相同的配置效果,这个类现在用作bean配置的平台。以下是AppContext类的代码。
@Configuration
public class AppContext {
@Bean
public Car car() {
Car car = new Car();
return car;
}
@Bean
public Company company() {
Company company = new Company();
return company;
}
@Bean
public Person person() {
Person person = new Person();
person.setCar(car());
person.setCompany(company());
return person;
}
}
在上面的代码中,以编程的方式将bean定义为基于Java配置的一部分。AppContext类现在就像applicationContext.xml文件一样充当着配置类的作用,这是通过@Configuration这个注解来实现的。@Configuration注解位于类的顶端,通过这个注解Spring会获知这个类是一个拥有bean定义和依赖项的配置类。@Bean注解用于定义一个bean,位于定义bean并实例化依赖项的方法顶端。bean的ID就是方法的名字,bean的类型就是方法返回类型。bean的依赖项可以通过bean中的setter方法进行设置。
创建bean还可以采用annotation(注解)的方式。采用annotation方式进行bean的创建就不再需要@Bean注解方式创建bean,Spring会自动搜索指定路径下面的Java类并将这些Java类注册成为Spring容器中的bean。这些Java类采用注解的方式进行标记,方便Spring框架进行识别。Spring目前主要提供了@Component、@Controller、@Service、@Repository这四种注解来定义一个bean。目前通过这四种方式定义bean之后所实现的效果是一样的。为了使得Spring能够正确地找到定义之后的这些bean,需要在AnnotationConfigWebApplicationContext的注册类AppContext中说明扫描的路径,需要通过注解@ComponentScan("com.spring")来定义扫描路径,如下面代码所示:
@Configuration
@ComponentScan("com.spring.test")
public class AppContext {
}
和以前的AppContext类相比,在这个新的AppContext类中少了那些以@Bean注解开头的定义bean的方法。现在如果需要定义一个新的bean,只需要在com.spring.test包下面定义一个Java类并用@Component、@Controller、@Service、@Repository四个中的任意一个注解即可。
使用注解的方式创建bean时,bean之间的依赖关系也是用注解的方式实现。有两个注解用来实现依赖注入,即@Autowired和@Resource,它们既可以写在字段上,也可以写在setter方法上。两者的不同在于@Autowired默认使用byType的方式进行注入,而@Resource默认使用byName的方式进行注入。以下代码是使用以注解@Autowired为例子的方式创建Car、Company、Person三个bean。
@Component
public class Car{
private String name = “myCar”;
//省略get/set方法
}
@Component
public class Company{
private String name = “myCompany”;
//省略get/set方法
}
@Component
public class Person{
@Autowired
private Car car;
@Autowired
private Company company;
//省略get/set方法
}
通过上面的方法创建bean并进行注入后,Spring容器中就有了Car、Company、Person三个实例,并且Person中的属性car和company也被注入了Car和Company的实例,整个Spring容器容纳了所需的所有bean,并且形成一个bean之间的关系网。需要说明的是,使用annotation创建bean并不是Java Config的特权,使用XML配置Spring的方式同样也可以使用annotation的方式创建bean,只不过需要在配置文件applicationContext.xml中开启使用注解,同样也需要声明扫描包的范围。
使用基于Java Config的方式配置Spring框架具有比较大的优势,主要体现在以下三个方面:
(1)基于Java Config的配置定义bean是定义在Java类中,这种定义方式符合程序员一贯的编程方式,相对于使用XML定义bean的方式,使用Java Config的方式能够减少编程思维的跳跃性,程序员不需要在Java类和XML文件中来回切换。
(2)使用Java类进行Spring配置可以在编译期间检查错误,这样在开发项目的时候能够随时发现错误并修改错误。而使用XML配置,只有在运行时才能发现各种配置及语法的错误,降低了开发效率。
(3)使用Java Config操作简单。只需要用@Configuration注解JavaConfig类,用每个方法来表示Bean并使用@Bean注解方法,每个方法名代表XML配置文件中的name。而在XML的配置中,创建bean以及bean之间的依赖关系需要通过大量的标签来实现。
Spring在目前的Java Web开发中具有非常广泛的应用,通过对比传统的使用XML配置的方式,对Spring新特性Java Config在Web项目开发中的应用进行了详细的研究。基于XML的配置方式是较为传统的配置方式,其灵活性好,项目部署后修改也方便[7]。而基于Java Config的配置方式配合使用annotation开发效率高,不容易出错,而且Java Config方式更符合程序员编程的风格,是以后Web项目开发的一种趋势。
[1] 李洋,孙永维,许冰,等.基于Ajax,Struts,Hibernate和Spring的J2EE架构[J]. 吉林大学学报(信息科学版),2011,29(6):576-584.
[2] 胡启敏,薛锦云,钟林辉. 基于Spring框架的轻量级J2EE架构与应用[J]. 计算机工程与应用,2008,44(5):115-118,133.
[3] 赵佳. 支持XML配置的IoC微容器设计[D]. 天津:天津大学,2007.
[4] 翟剑锟. Spring框架技术分析及应用研究[D].北京:中国科学院大学,2013.
[5] JOHNSON R,田佳伟. Spring framework 2.5介绍(上)[J]. 程序员,2008(1):90-95.
[6] JOHNSON R,田佳伟. Spring framework 2.5介绍(中)[J]. 程序员, 2008(2):101-106.
[7] MAK G, LONG J, RUBIO D. Spring Recipes[M]. Springer Apress, 2010.
Application of Spring′s new feature Java Config in Web development
Yang Ruidong1,2, Wang Yunfeng1, Zhang Haiying1
(1. Beijing Key Laboratory of Radio Frequency IC Technology for Next Generation Communications, Institute of Microelectronics of Chinese Academy of Sciences, Beijing 100029, China; 2. University of Chinese Academy of Sciences, Beijing 100049, China)
TP311
A
10.19358/j.issn.1674- 7720.2017.18.008
杨瑞东,王云峰,张海英.Spring新特性之Java Config在Web开发中的应用[J].微型机与应用,2017,36(18):26-29.
2017-03-28)
杨瑞东(1991-),男,硕士,学生,主要研究方向:Java Web开发、移动医疗。
王云峰(1981-),男,博士,副研究员,主要研究方向:便携式医疗电子设计。
张海英(1964-),女,博士,研究员,主要研究方向:健康电子医疗、射频集成电路。