1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.batch.core.configuration.support;
18
19 import java.io.IOException;
20
21 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
22 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
24 import org.springframework.context.ApplicationContext;
25 import org.springframework.context.ConfigurableApplicationContext;
26 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
27 import org.springframework.context.support.GenericApplicationContext;
28 import org.springframework.context.support.GenericXmlApplicationContext;
29 import org.springframework.core.io.Resource;
30 import org.springframework.util.Assert;
31
32
33
34
35
36
37
38
39 public class GenericApplicationContextFactory extends AbstractApplicationContextFactory {
40
41
42
43
44
45
46
47 public GenericApplicationContextFactory(Object resource) {
48 super(resource);
49 }
50
51
52
53
54 @Override
55 protected ConfigurableApplicationContext createApplicationContext(ConfigurableApplicationContext parent,
56 Object resource) {
57 if (resource instanceof Resource) {
58 return new ResourceXmlApplicationContext(parent, (Resource) resource);
59 }
60 if (resource instanceof Class<?>) {
61 return new ResourceAnnotationApplicationContext(parent, (Class<?>) resource);
62 }
63 if (resource instanceof String) {
64 return new ResourceAnnotationApplicationContext(parent, (String) resource);
65 }
66 throw new IllegalArgumentException("No application context could be created for resource type: "
67 + resource.getClass());
68 }
69
70 private abstract class ApplicationContextHelper {
71
72 private final DefaultListableBeanFactory parentBeanFactory;
73
74 private final ConfigurableApplicationContext parent;
75
76 public ApplicationContextHelper(ConfigurableApplicationContext parent, GenericApplicationContext context,
77 Object config) {
78 this.parent = parent;
79 if (parent != null) {
80 Assert.isTrue(parent.getBeanFactory() instanceof DefaultListableBeanFactory,
81 "The parent application context must have a bean factory of type DefaultListableBeanFactory");
82 parentBeanFactory = (DefaultListableBeanFactory) parent.getBeanFactory();
83 }
84 else {
85 parentBeanFactory = null;
86 }
87 context.setParent(parent);
88 context.setId(generateId(config));
89 loadConfiguration(config);
90 prepareContext(parent, context);
91 }
92
93 protected abstract String generateId(Object config);
94
95 protected abstract void loadConfiguration(Object config);
96
97 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
98 if (parentBeanFactory != null) {
99 GenericApplicationContextFactory.this.prepareBeanFactory(parentBeanFactory, beanFactory);
100 for (Class<? extends BeanFactoryPostProcessor> cls : getBeanFactoryPostProcessorClasses()) {
101 for (String name : parent.getBeanNamesForType(cls)) {
102 beanFactory.registerSingleton(name, ((BeanFactoryPostProcessor) parent.getBean(name)));
103 }
104 }
105 }
106 }
107
108 }
109
110 private final class ResourceXmlApplicationContext extends GenericXmlApplicationContext {
111
112 private final ApplicationContextHelper helper;
113
114
115
116
117 public ResourceXmlApplicationContext(ConfigurableApplicationContext parent, Resource resource) {
118 helper = new ApplicationContextHelper(parent, this, resource) {
119 @Override
120 protected String generateId(Object config) {
121 Resource resource = (Resource) config;
122 try {
123 return resource.getURI().toString();
124 }
125 catch (IOException e) {
126 return resource.toString();
127 }
128 }
129 @Override
130 protected void loadConfiguration(Object config) {
131 Resource resource = (Resource) config;
132 load(resource);
133 }
134 };
135 refresh();
136 }
137
138 @Override
139 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
140 super.prepareBeanFactory(beanFactory);
141 helper.prepareBeanFactory(beanFactory);
142 }
143
144 @Override
145 public String toString() {
146 return "ResourceXmlApplicationContext:" + getId();
147 }
148
149 }
150
151 private final class ResourceAnnotationApplicationContext extends AnnotationConfigApplicationContext {
152
153 private final ApplicationContextHelper helper;
154
155 public ResourceAnnotationApplicationContext(ConfigurableApplicationContext parent, Object resource) {
156 helper = new ApplicationContextHelper(parent, this, resource) {
157 @Override
158 protected String generateId(Object config) {
159 if (config instanceof Class) {
160 Class<?> type = (Class<?>) config;
161 return type.getName();
162 }
163 else {
164 return config.toString();
165 }
166 }
167 @Override
168 protected void loadConfiguration(Object config) {
169 if (config instanceof Class) {
170 Class<?> type = (Class<?>) config;
171 register(type);
172 }
173 else {
174 String pkg = (String) config;
175 scan(pkg);
176 }
177 }
178 };
179 refresh();
180 }
181
182 @Override
183 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
184 super.prepareBeanFactory(beanFactory);
185 helper.prepareBeanFactory(beanFactory);
186 }
187
188 @Override
189 public String toString() {
190 return "ResourceAnnotationApplicationContext:" + getId();
191 }
192
193 }
194
195 }