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.ProvidedServiceDescriptor;
16 import org.wamblee.system.RequiredServiceDescriptor;
17 import org.wamblee.system.Service;
18 import org.wamblee.system.ServiceDescriptor;
19 import org.wamblee.system.ServiceRegistry;
20 import org.wamblee.system.SystemAssembler;
21 import org.wamblee.system.SystemAssemblyException;
24 * Represents a system configured based on spring.
26 * @author Erik Brakkee
28 public class SpringSystem extends AbstractSubSystem {
31 * Singleton access to the service registry. Required while starting up.
33 static ThreadLocal<ServiceRegistry> REGISTRY = new ThreadLocal<ServiceRegistry>();
35 private String[] _configFiles;
36 private Map<String, ProvidedServiceDescriptor> _provided;
37 private Map<RequiredServiceDescriptor, String> _required;
39 * Parent application context containing required services.
41 private GenericApplicationContext _parentContext;
44 * Application context containing parsed objects.
46 private AbstractApplicationContext _context;
49 * Construcst a spring system.
54 * Spring config files to read.
56 * Map of bean name to service descriptor describing the bean
57 * names that the spring config files use for each required
60 * Map of bean name to service descriptor describing the bean
61 * names that the spring config files use for each required
64 public SpringSystem(String aName, ServiceRegistry aRegistry, String[] aConfigFiles,
65 Map<String, ProvidedServiceDescriptor> aProvided,
66 Map<RequiredServiceDescriptor, String> aRequired) {
67 super(aName, aRegistry, aProvided.values().toArray(new ServiceDescriptor[0]),
68 aRequired.keySet().toArray(new ServiceDescriptor[0]));
69 _configFiles = aConfigFiles;
70 _provided = aProvided;
71 _required = aRequired;
75 protected void doStart(String aContext,
76 Service[] aRequiredServices) {
77 ServiceRegistry old = REGISTRY.get();
79 REGISTRY.set(getRegistry());
82 registerRequiredServices(aRequiredServices);
86 exposeProvidedServices(aContext);
87 } catch (Exception e) {
88 throw new SystemAssemblyException(
89 "Failed to assemble spring system", e);
96 private void exposeProvidedServices(String aContext) {
97 // Call addService for each provided service.
99 for (String name : _provided.keySet()) {
100 Object svc = _context.getBean(name);
102 throw new IllegalArgumentException(aContext + ": service '"
103 + name + "' is null");
105 addService(aContext, _provided.get(name), svc);
109 private void parseConfigFiles() {
110 // Parse spring config files
112 _context = new ClassPathXmlApplicationContext((String[]) _configFiles,
116 private void registerRequiredServices(Service[] aRequiredServices) {
117 // Register required services in a parent context
119 // Register the Hibernate mapping files as a bean.
120 _parentContext = new GenericApplicationContext();
122 for (Service svc: aRequiredServices) {
123 String id = svc.getId();
124 ProvidedServiceDescriptor descriptor = svc.getDescriptor();
125 RequiredServiceDescriptor[] requiredServices = SystemAssembler.filterRequiredServices(descriptor,
127 for (RequiredServiceDescriptor required: requiredServices) {
128 String beanName = _required.get(required);
129 ConstructorArgumentValues cargs = new ConstructorArgumentValues();
130 cargs.addGenericArgumentValue(id);
131 BeanDefinition definition = new RootBeanDefinition(ProvidedServiceBean.class, cargs,
132 new MutablePropertyValues());
133 _parentContext.registerBeanDefinition(beanName, definition);
136 _parentContext.refresh();
140 protected void doStop() {