我发现许多我认识的Spring开发人员仍然不了解或使用Spring Java Configuration(aka JavaConfig)。 Spring 3.0引入了此功能,该功能使Spring可以完全用Java进行配置-不再需要XML! 我真的很喜欢使用JavaConfig,因为,好吧,它是Java! 这意味着它具有Java类型安全和IDE支持的所有优点:
- 打字错误生成编译错误–无需等待加载时间即可找到XML错字
- IDE重构工具将自动更新JavaConfig,因为它是常规Java
- 可以使用IDE自动导入功能来代替在XML中键入完全限定的类名
- IDE向下钻取功能
- IDE自动完成功能
- 我想您明白了,它适用于Java。
上面的某些功能确实内置在具有Spring支持的更高级的IDE中,但是最好不要依赖自定义IDE Spring支持来获得这些功能。 编译时检查对我来说是一个很大的检查。 我经常重构代码,更改字段名或移动或重命名Java文件经常会破坏XML Spring配置。 当然,在部署应用程序并收到Spring初始化错误之前,我通常不会意识到这一点。 现在,当我重构代码时,IDE会自动更新JavaConfig引用,因为它只是普通的Java。 另外,如果我忘记使用IDE的重构工具,那么JavaConfig中仍然会出现编译错误,该错误会在部署前提醒我出现问题。
让我展示一个有关XML配置如何转换为JavaConfig的基本示例。 首先,XML配置:
<beans>
<bean id="PersonService" class="com.codetutr.PersonService">
<constructor-arg ref="personDao" />
</bean>
<bean id="personDao" class="com.codetutr.dao.PersonDao">
<property name="endpoint" value="localhost" />
</bean>
</beans>
转换为JavaConfig:
package com.codetutr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.codetutr.dao.PersonDao;
import com.codetutr.service.PersonService;
@Configuration
public class AppConfig {
@Bean
public PersonService personService() {
return new PersonService(personDao());
}
@Bean
public PersonDao personDao() {
PersonDao personDao = new PersonDao();
personDao.setEndpoint("localhost");
return personDao;
}
}
这是一个非常简单的一对一转换。 每个<beans>
文档都转换为带有@Configuration
注释的Java类。 每个<bean>
元素都转换为带有@Bean
注释的单个方法。 方法的名称与bean ID相对应。 要在JavaConfig中引用另一个bean,只需调用所需bean的方法(请参见上面的personService
)。
我对Spring JavaConfig的另一种观察是,使用构造函数注入而不是setter注入更为自然-因为它导致了单行方法。 对我来说这是一个优点,因为我通常更喜欢构造函数注入。 如果一个类需要某些依赖项才能正常运行,我更喜欢在构造函数中要求它们。 这样,我可以确保将类初始化为有效状态。 我注意到,无论出于什么原因,构造器注入似乎在XML配置中很少使用。 也许constructor-arg
太难记了? 我不知道,但是我喜欢JavaConfig似乎可以带回一些东西。
现在,为了引导JavaConfig Application Context,Spring提供了一个新的ApplicationContext实现: AnnotationConfigApplicationContext
。 它的用法与使用ClassPathXmlApplicationContext
用法相同:
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
PersonService personService = ctx.getBean(PersonService.class);
或者,如果您在Web应用程序中:
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.codetutr.config.AppConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
请注意,可以为上面的contextConfigLocation
参数传递包名或类名。
或者最后,如果您使用的是Servlet 3的Java配置:
public class SpringWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
final AnnotationConfigWebApplicationContext springContext = new AnnotationConfigWebApplicationContext();
springContext.register(AppConfig.class);
final ServletRegistration.Dynamic springServlet = servletContext.addServlet("myServlet", new DispatcherServlet(springContext));
springServlet.setLoadOnStartup(1);
springServlet.addMapping("/*");
}
}
这篇文章只是刮擦了JavaConfig的表面。 我将在后续文章中介绍如何从其他@Configuration
类或XML文件导入bean以及如何使用自定义名称空间。 另外,请查看我的文章有关如何使用JavaConfig设置Spring-MVC应用程序 。
翻译自: https://www.javacodegeeks.com/2013/04/spring-java-configuration.html