1
2
3
4
5 package gboat2.base.dao.aspect;
6
7 import gboat2.base.core.dao.QuerySupport;
8 import gboat2.base.core.annotation.Relation;
9 import gboat2.base.core.annotation.Relations;
10 import gboat2.base.dao.util.GBoatDaoClassLoader;
11
12 import java.lang.reflect.Proxy;
13 import java.sql.SQLException;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import java.util.Set;
17
18 import org.apache.commons.collections.MapUtils;
19 import org.apache.commons.lang3.ClassUtils;
20 import org.apache.commons.lang3.ArrayUtils;
21 import org.apache.commons.lang3.ObjectUtils;
22 import org.apache.commons.lang3.StringUtils;
23 import org.aspectj.lang.JoinPoint;
24 import org.aspectj.lang.Signature;
25 import org.hibernate.SessionFactory;
26 import org.springframework.beans.factory.InitializingBean;
27 import org.springframework.jdbc.CannotGetJdbcConnectionException;
28
29
30
31
32
33
34
35
36
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
66
67
68
69
70 public class GboatSessionFactoryAspect implements InitializingBean{
71
72
73 private Map<String, SessionFactory> targetSessionFactorys;
74
75 public void dynamicSetSessionFactory(JoinPoint joinPoint) throws Exception {
76 Signature signature = joinPoint.getSignature();
77 Class<?> clazz = joinPoint.getTarget().getClass();
78 if (ClassUtils.isAssignable(clazz, Proxy.class)) {
79 clazz = signature.getDeclaringType();
80 }
81
82
83
84
85 Object[] arguments = joinPoint.getArgs();
86
87 String regex = null;
88 SessionFactory tempSf = null;
89 SessionFactory sessionFactory = null;
90 Set<Entry<String, SessionFactory>> entrySet = this.getTargetSessionFactorys().entrySet();
91 int i = 0;
92 targetSfLoop : for (Entry<String, SessionFactory> entry : entrySet) {
93 regex = StringUtils.trimToEmpty(entry.getKey());
94 tempSf = entry.getValue();
95
96
97
98
99
100
101
102
103 if (ArrayUtils.isEmpty(arguments))
104 break;
105
106 for (Object arg : arguments) {
107 if (arg instanceof Class) {
108 if(i == 0) {
109
110 validateVo((Class<?>) arg);
111 }
112
113
114 if (((Class<?>) arg).getName().matches(regex)) {
115 sessionFactory = tempSf;
116 break targetSfLoop;
117 }
118 } else if (arg instanceof Map) {
119
120 Object table = ((Map<?, ?>) arg).get(QuerySupport.PARAM_TABLENAME);
121 if (table != null) {
122 Class<?> tableClass = null;
123 if (table instanceof Class) {
124 tableClass = ((Class<?>) table);
125 } else if (table instanceof CharSequence) {
126 GBoatDaoClassLoader daoClassLoader = GBoatDaoClassLoader.getInstance();
127 if (daoClassLoader == null)
128 throw new IllegalStateException(
129 "Gboat2 DAO Bundle 的类加载器没有被实例化,无法加载 PO 或 VO [" + table + "]");
130
131 tableClass = daoClassLoader.loadClass(table.toString());
132 }
133
134 if (tableClass != null) {
135 if (i == 0) {
136
137 validateVo(tableClass);
138 }
139
140 if (tableClass.getName().matches(regex)) {
141 sessionFactory = tempSf;
142 break targetSfLoop;
143 }
144 }
145 }
146 } else if(arg != null && arguments.length == 1) {
147
148 if (arg.getClass().getName().matches(regex)) {
149 sessionFactory = tempSf;
150 break targetSfLoop;
151 }
152 }
153 }
154 i++;
155 }
156
157 if(sessionFactory == null) {
158 SessionFactoryHolder.clearSessionFactory();
159 } else {
160 SessionFactoryHolder.setSessionFactory(sessionFactory);
161 }
162 }
163
164
165
166
167
168
169
170
171
172 public void validateVo(Class<?> voClass){
173 if(voClass == null)
174 return;
175
176 Relations relations = voClass.getAnnotation(Relations.class);
177 if(relations == null)
178 return;
179
180 String baseClassName = relations.base().getName();
181 SessionFactory baseSessionFactory = null;
182 Set<Entry<String, SessionFactory>> entrySet = getTargetSessionFactorys().entrySet();
183 for (Entry<String, SessionFactory> entry : entrySet) {
184 if(baseClassName.matches(entry.getKey())) {
185 baseSessionFactory = entry.getValue();
186 break;
187 }
188 }
189
190 Relation[] array = relations.value();
191 SessionFactory referSessionFactory = null;
192 for (Relation relation : array) {
193 String referClassName = relation.refer().getName();
194 for (Entry<String, SessionFactory> entry : entrySet) {
195 if(referClassName.matches(entry.getKey())) {
196 referSessionFactory = entry.getValue();
197 break;
198 }
199 }
200
201
202
203 if(!ObjectUtils.equals(baseSessionFactory, referSessionFactory))
204 throw new CannotGetJdbcConnectionException("VO [" + voClass.getName() + "] 对象所关联的 PO 类由不同的 SessionFactory 进行管理",
205 new SQLException("baseClass[" + baseClassName + "] --> " + baseSessionFactory + ", referClass[" + referClassName + "] -->" + referSessionFactory));
206 }
207 }
208
209 public Map<String, SessionFactory> getTargetSessionFactorys() {
210 return targetSessionFactorys;
211 }
212
213 public void setTargetSessionFactorys(Map<String, SessionFactory> targetSessionFactorys) {
214 this.targetSessionFactorys = targetSessionFactorys;
215 }
216
217 @Override
218 public void afterPropertiesSet() throws Exception {
219 if(MapUtils.isEmpty(this.getTargetSessionFactorys()))
220 throw new IllegalArgumentException(getClass().getName() + " 切面的 targetSessionFactorys 属性不能为空");
221 }
222
223 }