1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.batch.core.listener;
17
18 import static org.springframework.batch.support.MethodInvokerUtils.getMethodInvokerByAnnotation;
19 import static org.springframework.batch.support.MethodInvokerUtils.getMethodInvokerForInterface;
20
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
26
27 import org.springframework.aop.TargetSource;
28 import org.springframework.aop.framework.Advised;
29 import org.springframework.aop.framework.ProxyFactory;
30 import org.springframework.aop.support.DefaultPointcutAdvisor;
31 import org.springframework.batch.support.MethodInvoker;
32 import org.springframework.batch.support.MethodInvokerUtils;
33 import org.springframework.beans.factory.FactoryBean;
34 import org.springframework.beans.factory.InitializingBean;
35 import org.springframework.core.Ordered;
36 import org.springframework.util.Assert;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 @SuppressWarnings("rawtypes")
66 public abstract class AbstractListenerFactoryBean implements FactoryBean, InitializingBean {
67
68 private Object delegate;
69
70 private Map<String, String> metaDataMap;
71
72 @Override
73 public Object getObject() {
74
75 if (metaDataMap == null) {
76 metaDataMap = new HashMap<String, String>();
77 }
78
79
80
81 for (ListenerMetaData metaData : this.getMetaDataValues()) {
82 if (!metaDataMap.containsKey(metaData.getPropertyName())) {
83
84 metaDataMap.put(metaData.getPropertyName(), null);
85 }
86 }
87
88 Set<Class<?>> listenerInterfaces = new HashSet<Class<?>>();
89
90
91
92 Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>();
93 boolean synthetic = false;
94 for (Entry<String, String> entry : metaDataMap.entrySet()) {
95
96 final ListenerMetaData metaData = this.getMetaDataFromPropertyName(entry.getKey());
97 Set<MethodInvoker> invokers = new HashSet<MethodInvoker>();
98
99 MethodInvoker invoker;
100
101 invoker = getMethodInvokerForInterface(metaData.getListenerInterface(), metaData.getMethodName(), delegate,
102 metaData.getParamTypes());
103 if (invoker != null) {
104 invokers.add(invoker);
105 }
106
107 invoker = getMethodInvokerByName(entry.getValue(), delegate, metaData.getParamTypes());
108 if (invoker != null) {
109 invokers.add(invoker);
110 synthetic = true;
111 }
112
113 invoker = getMethodInvokerByAnnotation(metaData.getAnnotation(), delegate, metaData.getParamTypes());
114 if (invoker != null) {
115 invokers.add(invoker);
116 synthetic = true;
117 }
118
119 if (!invokers.isEmpty()) {
120 invokerMap.put(metaData.getMethodName(), invokers);
121 listenerInterfaces.add(metaData.getListenerInterface());
122 }
123
124 }
125
126 if (listenerInterfaces.isEmpty()) {
127 listenerInterfaces.add(this.getDefaultListenerClass());
128 }
129
130 if (!synthetic) {
131 int count = 0;
132 for (Class<?> listenerInterface : listenerInterfaces) {
133 if (listenerInterface.isInstance(delegate)) {
134 count++;
135 }
136 }
137
138 if (count == listenerInterfaces.size()) {
139 return delegate;
140 }
141 }
142
143 boolean ordered = false;
144 if (delegate instanceof Ordered) {
145 ordered = true;
146 listenerInterfaces.add(Ordered.class);
147 }
148
149
150
151 ProxyFactory proxyFactory = new ProxyFactory();
152 if (delegate instanceof Advised) {
153 proxyFactory.setTargetSource(((Advised) delegate).getTargetSource());
154 }
155 else {
156 proxyFactory.setTarget(delegate);
157 }
158 proxyFactory.setInterfaces(listenerInterfaces.toArray(new Class[0]));
159 proxyFactory.addAdvisor(new DefaultPointcutAdvisor(new MethodInvokerMethodInterceptor(invokerMap, ordered)));
160 return proxyFactory.getProxy();
161
162 }
163
164 protected abstract ListenerMetaData getMetaDataFromPropertyName(String propertyName);
165
166 protected abstract ListenerMetaData[] getMetaDataValues();
167
168 protected abstract Class<?> getDefaultListenerClass();
169
170 protected MethodInvoker getMethodInvokerByName(String methodName, Object candidate, Class<?>... params) {
171 if (methodName != null) {
172 return MethodInvokerUtils.getMethodInvokerByName(candidate, methodName, false, params);
173 }
174 else {
175 return null;
176 }
177 }
178
179 @Override
180 public boolean isSingleton() {
181 return true;
182 }
183
184 public void setDelegate(Object delegate) {
185 this.delegate = delegate;
186 }
187
188 public void setMetaDataMap(Map<String, String> metaDataMap) {
189 this.metaDataMap = metaDataMap;
190 }
191
192 @Override
193 public void afterPropertiesSet() throws Exception {
194 Assert.notNull(delegate, "Delegate must not be null");
195 }
196
197
198
199
200
201
202
203
204
205 public static boolean isListener(Object target, Class<?> listenerType, ListenerMetaData[] metaDataValues) {
206 if (target == null) {
207 return false;
208 }
209 if (listenerType.isInstance(target)) {
210 return true;
211 }
212 if (target instanceof Advised) {
213 TargetSource targetSource = ((Advised) target).getTargetSource();
214 if (targetSource != null && targetSource.getTargetClass() != null
215 && listenerType.isAssignableFrom(targetSource.getTargetClass())) {
216 return true;
217 }
218 }
219 for (ListenerMetaData metaData : metaDataValues) {
220 if (MethodInvokerUtils.getMethodInvokerByAnnotation(metaData.getAnnotation(), target) != null) {
221 return true;
222 }
223 }
224 return false;
225 }
226 }