spring - 在SpringConfig.class中使用来自config.xml的bean

时间:2017-04-24 15:40:16

标签: xml spring web-applications import spring-annotations

我有一些上下文从部署更改为部署,有些上下文对所有部署都是不变的。与部署相关的位位于jar或war外部的config.xml文件中。静态上下文内容位于注释配置类中。诀窍是注释配置使用config.xml中的bean。对于应用程序,它将在config类中导入。但对于webapp,它无法找到该文件。

SpringConfig类

@Component
@Configuration
@ImportResource("file:./config.xml")
public class SpringConfig {

   @Autowired private String local_timezone_string;
   @Autowired private String startDateFormatString;
   @Autowired private String startDateString;

   @Bean
   public TimeZone localTimeZone() {
      return TimeZone.getTimeZone(local_timezone_string);
   }

   @Bean
   public SimpleDateFormat startDateFormat() {
      SimpleDateFormat sdf = new SimpleDateFormat(startDateFormatString);
      sdf.setTimeZone(localTimeZone());
      return sdf;
   }

   @Bean
   public long jaceThreadStartDate() throws ParseException {
      return startDateFormat().parse(jaceThreadStartDateString).getTime();
   }

   ... a bunch of other beans
}

和config.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="local_timezone_string" class="java.lang.String"><constructor-arg value="Canada/Atlantic"/></bean>
   <bean id="startDateFormatString" class="java.lang.String"><constructor-arg value="yyyy-MM-dd"/></bean>
   <bean id="startDateString" class="java.lang.String"><constructor-arg value="2017-04-06"/></bean>

   ... other beans

</beans>

config.xml未包含在jar中,因此SpringConfig在部署文件夹中查找config.xml并使用特定于部署的上下文。但是当通过WebApplicationInitializer在webapp中部署SpringConfig时,它无法再找到config.xml。当然。那么,如何将依赖于部署的上下文中的bean加载到webapp中的静态上下文中?有没有办法告诉AnnotationConfigApplicationContext在从webapp中的xml配置中注册bean之后扫描包的@Configuration和@Components

我想的可能是一个派生自AnnotationConfigWebApplicationContext的类 - 在构造函数中 - 调用setParent(config.xml context)然后调用AnnotationConfigWebApplicationContext(SpringConfig.class)。

甚至:而不是调用AnnotationConfigApplicationContext(String ... basePackages),而是调用AnnotationConfigApplicationContext(),然后调用setParent(...),然后扫描(...)。

1 个答案:

答案 0 :(得分:0)

所以有一种方法可以使用setParent()和scan()。

@Component
@Configuration
public class SpringConfig {

    private static final Logger log = Logger.getLogger(SpringConfig.class);
    @Autowired private DriverManagerDataSource pgDataSource;
    @Autowired private String local_timezone_string;
    @Autowired private String startDateFormatString;
    @Autowired private String startDateString;

    private static ApplicationContext getVariableContext() throws Exception {

        ApplicationContext variableContext = null;
        try {
            variableContext = new FileSystemXmlApplicationContext("./config.xml");
            log.info("got config.xml from file system");
        } catch (Exception e) {
            try {
                variableContext = new ClassPathXmlApplicationContext("config.xml");
                log.info("got config.xml from class path");
            } catch (Exception ex) {
                log.info("failed to get config.xml");
                throw new Exception(...);
            }
        }
        return variableContext;
    }

    public static WebApplicationContext getWebApplicationContext() throws ServletException {

        try {
            ApplicationContext variableContext = getVariableContext();
            AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
            appContext.setParent(variableContext);
            appContext.scan(
                    "com.us.systemdiagnostics",
                    "com.us.systemdiagnostics.webservice"
            );
            appContext.refresh();
            return appContext;

        } catch (Exception e) {
            throw new ServletException(...);
        }
    }

    public static ApplicationContext getStandAloneApplicationContext() throws ServletException {

        try {
            ApplicationContext variableContext = getVariableContext();
            AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
            appContext.setParent(variableContext);
            appContext.scan(
                    "com.us.systemdiagnostics",
                    "com.us.systemdiagnostics.webservice"
            );
            appContext.refresh();
            return appContext;

        } catch (Exception e) {
            throw new Exception(...);
        }
    }

    ... beans, etc ...
}