1 package org.wamblee.system.spring;
5 import org.springframework.beans.MutablePropertyValues;
6 import org.springframework.beans.factory.config.BeanDefinition;
7 import org.springframework.beans.factory.config.ConstructorArgumentValues;
8 import org.springframework.beans.factory.support.RootBeanDefinition;
9 import org.springframework.context.ApplicationContext;
10 import org.springframework.context.support.AbstractApplicationContext;
11 import org.springframework.context.support.ClassPathXmlApplicationContext;
12 import org.springframework.context.support.GenericApplicationContext;
13 import org.wamblee.system.AbstractSubSystem;
14 import org.wamblee.system.CompositeSystem;
15 import org.wamblee.system.Service;
16 import org.wamblee.system.ServiceDescriptor;
17 import org.wamblee.system.ServiceRegistry;
18 import org.wamblee.system.SystemAssemblyException;
21 * Represents a system configured based on spring.
23 public class SpringSystem extends AbstractSubSystem {
26 * Singleton access to the service registry. Required while starting up.
28 static ThreadLocal<ServiceRegistry> REGISTRY = new ThreadLocal<ServiceRegistry>();
30 private String[] _configFiles;
31 private Map<String, ServiceDescriptor> _provided;
32 private Map<ServiceDescriptor, String> _required;
34 * Parent application context containing required services.
36 private GenericApplicationContext _parentContext;
39 * Application context containing parsed objects.
41 private AbstractApplicationContext _context;
44 * Construcst a spring system.
49 * Spring config files to read.
51 * Map of bean name to service descriptor describing the bean
52 * names that the spring config files use for each required
55 * Map of bean name to service descriptor describing the bean
56 * names that the spring config files use for each required
59 public SpringSystem(String aName, ServiceRegistry aRegistry, String[] aConfigFiles,
60 Map<String, ServiceDescriptor> aProvided,
61 Map<ServiceDescriptor, String> aRequired) {
62 super(aName, aRegistry, aProvided.values().toArray(new ServiceDescriptor[0]),
63 aRequired.keySet().toArray(new ServiceDescriptor[0]));
64 _configFiles = aConfigFiles;
65 _provided = aProvided;
66 _required = aRequired;
70 protected void doStart(String aContext,
71 Service[] aRequiredServices) {
72 ServiceRegistry old = REGISTRY.get();
74 REGISTRY.set(getRegistry());
77 registerRequiredServices(aRequiredServices);
81 exposeProvidedServices(aContext);
82 } catch (Exception e) {
83 throw new SystemAssemblyException(
84 "Failed to assemble spring system", e);
91 private void exposeProvidedServices(String aContext) {
92 // Call addService for each provided service.
94 for (String name : _provided.keySet()) {
95 Object svc = _context.getBean(name);
97 throw new IllegalArgumentException(aContext + ": service '"
98 + name + "' is null");
100 addService(aContext, _provided.get(name), svc);
104 private void parseConfigFiles() {
105 // Parse spring config files
107 _context = new ClassPathXmlApplicationContext((String[]) _configFiles,
111 private void registerRequiredServices(Service[] aRequiredServices) {
112 // Register required services in a parent context
114 // Register the Hibernate mapping files as a bean.
115 _parentContext = new GenericApplicationContext();
117 for (Service svc: aRequiredServices) {
118 String id = svc.getId();
119 ServiceDescriptor descriptor = svc.getDescriptor();
120 String beanName = _required.get(descriptor);
121 ConstructorArgumentValues cargs = new ConstructorArgumentValues();
122 cargs.addGenericArgumentValue(id);
123 BeanDefinition definition = new RootBeanDefinition(ProvidedServiceBean.class, cargs,
124 new MutablePropertyValues());
125 _parentContext.registerBeanDefinition(beanName, definition);
127 _parentContext.refresh();
131 protected void doStop() {