├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── settings.gradle
└── src
└── main
└── java
└── org
└── smart4j
└── framework
├── FrameworkConstant.java
├── HelperLoader.java
├── InstanceFactory.java
├── aop
├── AopHelper.java
├── AspectProxy.java
├── annotation
│ ├── Aspect.java
│ └── AspectOrder.java
└── proxy
│ ├── Proxy.java
│ ├── ProxyChain.java
│ └── ProxyManager.java
├── core
├── ClassHelper.java
├── ClassScanner.java
├── ConfigHelper.java
├── bean
│ └── BaseBean.java
├── fault
│ └── InitializationError.java
└── impl
│ ├── DefaultClassScanner.java
│ └── support
│ ├── AnnotationClassTemplate.java
│ ├── ClassTemplate.java
│ └── SupperClassTemplate.java
├── dao
├── DataAccessor.java
├── DatabaseHelper.java
├── SqlHelper.java
├── bean
│ └── Pager.java
└── impl
│ └── DefaultDataAccessor.java
├── ds
├── DataSourceFactory.java
└── impl
│ ├── AbstractDataSourceFactory.java
│ └── DefaultDataSourceFactory.java
├── ioc
├── BeanHelper.java
├── IocHelper.java
└── annotation
│ ├── Bean.java
│ ├── Impl.java
│ └── Inject.java
├── mvc
├── ActionHelper.java
├── ContainerListener.java
├── DataContext.java
├── DispatcherServlet.java
├── Handler.java
├── HandlerExceptionResolver.java
├── HandlerInvoker.java
├── HandlerMapping.java
├── Requester.java
├── UploadHelper.java
├── ViewResolver.java
├── annotation
│ ├── Action.java
│ └── Request.java
├── bean
│ ├── Multipart.java
│ ├── Multiparts.java
│ ├── Params.java
│ ├── Result.java
│ └── View.java
├── fault
│ ├── AuthcException.java
│ ├── AuthzException.java
│ └── UploadException.java
└── impl
│ ├── DefaultHandlerExceptionResolver.java
│ ├── DefaultHandlerInvoker.java
│ ├── DefaultHandlerMapping.java
│ └── DefaultViewResolver.java
├── orm
├── DataSet.java
├── EntityHelper.java
└── annotation
│ ├── Column.java
│ ├── Entity.java
│ └── Table.java
├── plugin
├── Plugin.java
├── PluginHelper.java
├── PluginProxy.java
└── WebPlugin.java
├── test
├── OrderedRunner.java
└── annotation
│ └── TestOrder.java
├── tx
├── TransactionProxy.java
└── annotation
│ ├── Service.java
│ └── Transaction.java
└── util
├── ArrayUtil.java
├── CastUtil.java
├── ClassUtil.java
├── CodecUtil.java
├── CollectionUtil.java
├── DateUtil.java
├── FileUtil.java
├── JsonUtil.java
├── MapUtil.java
├── ObjectUtil.java
├── PropsUtil.java
├── StreamUtil.java
├── StringUtil.java
└── WebUtil.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Maven #
2 | target/
3 |
4 | # IDEA #
5 | .idea/
6 | *.iml
7 |
8 | # Eclipse #
9 | .settings/
10 | .classpath
11 | .project
12 | /gradlew.bat
13 | /.gradle
14 | /gradle
15 | /gradlew
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Smart Framework
2 |
3 | ## 简介
4 |
5 | ### 1. 它是一款轻量级 Java Web 框架
6 |
7 | - 内置 IOC、AOP、ORM、DAO、MVC 等特性
8 | - 基于 Servlet 3.0 规范
9 | - 使用 Java 注解取代 XML 配置
10 |
11 | ### 2. 它使应用充分做到“前后端分离”
12 |
13 | - 客户端可使用 HTML 或 JSP 作为视图模板
14 | - 服务端可发布 REST 服务(使用 REST 插件)
15 | - 客户端通过 AJAX 获取服务端数据并进行界面渲染
16 |
17 | ### 3. 它可提高应用程序的开发效率
18 |
19 | - 面向基于 Web 的中小规模的应用程序
20 | - 新手能在较短时间内入门
21 | - 核心具有良好的定制性且插件易于扩展
22 |
23 | 
24 |
25 | ## 入门
26 |
27 | ### 1. 创建一个 Maven Web 工程
28 |
29 | 整个工程的目录结构如下:
30 |
31 | ```
32 | smart-sample/
33 | ┗ src/
34 | ┗ main/
35 | ┗ java/
36 | ┗ resources/
37 | ┗ webapp/
38 | ┗ pom.xml
39 | ```
40 |
41 | 在 `java` 目录下,创建以下包名目录结构:
42 |
43 | ```
44 | org/
45 | ┗ smart4j/
46 | ┗ sample/
47 | ┗ action/
48 | ┗ entity/
49 | ┗ service/
50 | ```
51 |
52 | 可见,基础包名为:org.smart4j.sample,下面的配置中会用到它。
53 |
54 | ### 2. 配置 Maven 依赖
55 |
56 | 编辑 `pom.xml` 文件,添加 `smart-framework` 依赖:
57 |
58 | ```xml
59 |
60 | org.smart4j
61 | smart-framework
62 | [版本号]
63 |
64 | ```
65 |
66 | > 提示:需要指定具体的版本号。若使用相关 Smart 插件,则需分别配置。
67 |
68 | ### 3. 编写 Smart 配置
69 |
70 | 在 `resources` 目录下,创建一个名为 `smart.properties` 的文件,内容如下:
71 |
72 | ```
73 | smart.framework.app.base_package=org.smart4j.sample
74 | smart.framework.app.home_page=/users
75 |
76 | smart.framework.jdbc.driver=com.mysql.jdbc.Driver
77 | smart.framework.jdbc.url=jdbc:mysql://localhost:3306/smart-sample
78 | smart.framework.jdbc.username=root
79 | smart.framework.jdbc.password=root
80 | ```
81 |
82 | > 提示:需根据实际情况修改以上配置。
83 |
84 | ### 4. 编写 Entity 类
85 |
86 | ```java
87 | package org.smart4j.sample.entity;
88 |
89 | import org.smart4j.framework.orm.annotation.Entity;
90 |
91 | @Entity
92 | public class User {
93 |
94 | private long id;
95 |
96 | private String username;
97 |
98 | private String password;
99 |
100 | // getter/setter
101 | }
102 | ```
103 |
104 | ### 5. 编写 Service 接口及其实现
105 |
106 | Service 接口
107 |
108 | ```java
109 | package org.smart4j.sample.service;
110 |
111 | import java.util.List;
112 | import java.util.Map;
113 | import org.smart4j.sample.entity.User;
114 |
115 | public interface UserService {
116 |
117 | List findUserList();
118 |
119 | User findUser(long id);
120 |
121 | boolean saveUser(Map fieldMap);
122 |
123 | boolean updateUser(long id, Map fieldMap);
124 |
125 | boolean deleteUser(long id);
126 | }
127 | ```
128 |
129 | Service 实现
130 |
131 | ```java
132 | package org.smart4j.sample.service.impl;
133 |
134 | import java.util.List;
135 | import java.util.Map;
136 | import org.smart4j.framework.orm.DataSet;
137 | import org.smart4j.framework.tx.annotation.Service;
138 | import org.smart4j.framework.tx.annotation.Transaction;
139 | import org.smart4j.sample.entity.User;
140 | import org.smart4j.sample.service.UserService;
141 |
142 | @Service
143 | public class UserServiceImpl implements UserService {
144 |
145 | @Override
146 | public List findUserList() {
147 | return DataSet.selectList(User.class);
148 | }
149 |
150 | @Override
151 | public User findUser(long id) {
152 | return DataSet.select(User.class, "id = ?", id);
153 | }
154 |
155 | @Override
156 | @Transaction
157 | public boolean saveUser(Map fieldMap) {
158 | return DataSet.insert(User.class, fieldMap);
159 | }
160 |
161 | @Override
162 | @Transaction
163 | public boolean updateUser(long id, Map fieldMap) {
164 | return DataSet.update(User.class, fieldMap, "id = ?", id);
165 | }
166 |
167 | @Override
168 | @Transaction
169 | public boolean deleteUser(long id) {
170 | return DataSet.delete(User.class, "id = ?", id);
171 | }
172 | }
173 | ```
174 |
175 | ### 5. 编写 Action 类
176 |
177 | ```java
178 | package org.smart4j.sample.action;
179 |
180 | import java.util.List;
181 | import java.util.Map;
182 | import org.smart4j.framework.ioc.annotation.Inject;
183 | import org.smart4j.framework.mvc.DataContext;
184 | import org.smart4j.framework.mvc.annotation.Action;
185 | import org.smart4j.framework.mvc.annotation.Request;
186 | import org.smart4j.framework.mvc.bean.Params;
187 | import org.smart4j.framework.mvc.bean.Result;
188 | import org.smart4j.framework.mvc.bean.View;
189 | import org.smart4j.sample.entity.User;
190 | import org.smart4j.sample.service.UserService;
191 |
192 | @Action
193 | public class UserAction {
194 |
195 | @Inject
196 | private UserService userService;
197 |
198 | @Request.Get("/users")
199 | public View index() {
200 | List userList = userService.findUserList();
201 | DataContext.Request.put("userList", userList);
202 | return new View("user.jsp");
203 | }
204 |
205 | @Request.Get("/user")
206 | public View create() {
207 | return new View("user_create.jsp");
208 | }
209 |
210 | @Request.Post("/user")
211 | public Result save(Params params) {
212 | Map fieldMap = params.getFieldMap();
213 | boolean result = userService.saveUser(fieldMap);
214 | return new Result(result);
215 | }
216 |
217 | @Request.Get("/user/{id}")
218 | public View edit(long id) {
219 | User user = userService.findUser(id);
220 | DataContext.Request.put("user", user);
221 | return new View("user_edit.jsp");
222 | }
223 |
224 | @Request.Put("/user/{id}")
225 | public Result update(long id, Params params) {
226 | Map fieldMap = params.getFieldMap();
227 | boolean result = userService.updateUser(id, fieldMap);
228 | return new Result(result);
229 | }
230 |
231 | @Request.Delete("/user/{id}")
232 | public Result delete(long id) {
233 | boolean result = userService.deleteUser(id);
234 | return new Result(result);
235 | }
236 | }
237 | ```
238 |
239 | ### 6. 编写视图
240 |
241 | 在 Action 中使用了 JSP 作为视图展现技术,需要编写以下 JSP 文件:
242 |
243 | - user.jsp
244 | - user_list.jsp
245 | - user_create.jsp
246 | - user_edit.jsp
247 |
248 | > 提示:更多相关细节,请参考 [Smart Sample](http://git.oschina.net/huangyong/smart-sample) 示例。
249 |
250 | ## 提高
251 |
252 | TODO
253 |
254 | ## 示例
255 |
256 | - Smart Sample:http://git.oschina.net/huangyong/smart-sample
257 | - Smart Bootstrap:http://git.oschina.net/huangyong/smart-bootstrap
258 | - Smart REST Server:http://git.oschina.net/huangyong/smart-rest-server
259 | - Smart REST Client:http://git.oschina.net/huangyong/smart-rest-client
260 |
261 | ## 附录
262 |
263 | ### 相关插件
264 |
265 | > 注意:插件依赖于框架,不能独立使用。
266 |
267 | - [smart-plugin-security](http://git.oschina.net/huangyong/smart-plugin-security) -- 基于 [Apache Shiro](http://shiro.apache.org/) 的安全控制插件
268 | - [smart-plugin-cache](http://git.oschina.net/huangyong/smart-plugin-cache) -- 基于注解的 Cache 插件
269 | - [smart-plugin-i18n](http://git.oschina.net/huangyong/smart-plugin-i18n) -- 通用的 I18N 插件
270 | - [smart-plugin-mail](http://git.oschina.net/huangyong/smart-plugin-mail) -- 基于 [Apache Commons Email](http://commons.apache.org/proper/commons-email/) 的邮件收发插件
271 | - [smart-plugin-template](http://git.oschina.net/huangyong/smart-plugin-template) -- 基于 [Apache Velocity](http://velocity.apache.org/) 的模板引擎插件
272 | - [smart-plugin-job](http://git.oschina.net/huangyong/smart-plugin-job) -- 基于 [Quartz](http://www.quartz-scheduler.org/) 的作业调度插件
273 | - [smart-plugin-soap](http://git.oschina.net/huangyong/smart-plugin-soap) -- 基于 [Apache CXF](http://cxf.apache.org/) 的 SOAP Web Service 插件
274 | - [smart-plugin-rest](http://git.oschina.net/huangyong/smart-plugin-rest) -- 基于 [Apache CXF](http://cxf.apache.org/) 的 REST Web Service 插件
275 | - [smart-plugin-hessian](http://git.oschina.net/huangyong/smart-plugin-hessian) -- 基于 [Hessian](http://hessian.caucho.com/) 的 RMI 插件
276 | - [smart-plugin-xmlrpc](http://git.oschina.net/huangyong/smart-plugin-xmlrpc) -- 基于 [Apache XML-RPC](http://ws.apache.org/xmlrpc/) 的 XML-RPC 插件
277 | - [smart-plugin-search](http://git.oschina.net/huangyong/smart-plugin-search) -- 基于 [Apache Lucene](http://lucene.apache.org/) 的搜索引擎插件
278 | - [smart-plugin-mybatis](http://git.oschina.net/free/smart-plugin-mybatis) -- 基于 [MyBatis](http://mybatis.github.io/mybatis-3/) 的数据持久层插件
279 | - [smart-plugin-args](http://git.oschina.net/free/smart-plugin-args) -- 强大的 Action 方法参数绑定的插件
280 | - [smart-plugin-c3p0](http://git.oschina.net/huangyong/smart-plugin-c3p0) -- 基于 [C3P0](http://sourceforge.net/projects/c3p0/) 的连接池插件
281 | - [smart-plugin-druid](http://git.oschina.net/huangyong/smart-plugin-druid) -- 基于 [Druid](https://github.com/alibaba/druid) 的连接池插件
282 |
283 | ### 相关模块
284 |
285 | > 注意:模块不依赖于框架,可以独立使用。
286 |
287 | - [smart-sso](http://git.oschina.net/huangyong/smart-sso) -- 基于 [Jasig CAS](http://www.jasig.org/cas) 的 SSO 模块
288 | - [smart-cache](http://git.oschina.net/huangyong/smart-cache) -- 通用的 Cache 模块与基于内存的实现
289 | - [smart-cache-ehcache](http://git.oschina.net/huangyong/smart-cache-ehcache) -- 基于 [EhCache](http://www.ehcache.org/) 的 Cache 模块
290 | - [smart-cache-redis](http://git.oschina.net/lujianing/smart-cache-redis) -- 基于 [Jedis](https://github.com/xetorthio/jedis/) 的 Cache 模块
291 |
292 | ### 参考资料
293 |
294 | - Smart 系列博文:http://my.oschina.net/huangyong/blog/158380
295 | - Maven 那点事儿:http://my.oschina.net/huangyong/blog/194583
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'war'
2 |
3 | group = 'org.smart4j'
4 | version = '2.3.3-SNAPSHOT'
5 |
6 | description = """smart-framework"""
7 |
8 | sourceCompatibility = 1.6
9 | targetCompatibility = 1.6
10 |
11 | repositories {
12 | jcenter()
13 | }
14 |
15 | dependencies {
16 | compile 'org.slf4j:slf4j-log4j12:1.7.5',
17 | 'org.codehaus.jackson:jackson-mapper-asl:1.9.13',
18 | 'org.codehaus.jackson:jackson-jaxrs:1.9.13',
19 | 'cglib:cglib:2.2.2',
20 | 'commons-lang:commons-lang:2.4',
21 | 'commons-collections:commons-collections:3.2.1',
22 | 'commons-beanutils:commons-beanutils:1.8.3',
23 | 'commons-dbcp:commons-dbcp:1.4',
24 | 'commons-dbutils:commons-dbutils:1.5',
25 | 'commons-fileupload:commons-fileupload:1.3',
26 | 'commons-codec:commons-codec:1.8'
27 | testCompile 'junit:junit:4.11'
28 | providedCompile "javax.servlet:javax.servlet-api:3.0.1"
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'smart-framework'
2 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/FrameworkConstant.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework;
2 |
3 | import org.smart4j.framework.core.ConfigHelper;
4 |
5 | public interface FrameworkConstant {
6 |
7 | String UTF_8 = "UTF-8";
8 |
9 | String CONFIG_PROPS = "smart.properties";
10 | String SQL_PROPS = "smart-sql.properties";
11 |
12 | String PLUGIN_PACKAGE = "org.smart4j.plugin";
13 |
14 | String JSP_PATH = ConfigHelper.getString("smart.framework.app.jsp_path", "/WEB-INF/jsp/");
15 | String WWW_PATH = ConfigHelper.getString("smart.framework.app.www_path", "/www/");
16 | String HOME_PAGE = ConfigHelper.getString("smart.framework.app.home_page", "/index.html");
17 | int UPLOAD_LIMIT = ConfigHelper.getInt("smart.framework.app.upload_limit", 10);
18 |
19 | String PK_NAME = "id";
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/HelperLoader.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework;
2 |
3 | import org.smart4j.framework.aop.AopHelper;
4 | import org.smart4j.framework.dao.DatabaseHelper;
5 | import org.smart4j.framework.ioc.BeanHelper;
6 | import org.smart4j.framework.ioc.IocHelper;
7 | import org.smart4j.framework.mvc.ActionHelper;
8 | import org.smart4j.framework.orm.EntityHelper;
9 | import org.smart4j.framework.plugin.PluginHelper;
10 | import org.smart4j.framework.util.ClassUtil;
11 |
12 | /**
13 | * 加载相应的 Helper 类
14 | *
15 | * @author huangyong
16 | * @since 2.0
17 | */
18 | public final class HelperLoader {
19 |
20 | public static void init() {
21 | // 定义需要加载的 Helper 类
22 | Class>[] classList = {
23 | DatabaseHelper.class,
24 | EntityHelper.class,
25 | ActionHelper.class,
26 | BeanHelper.class,
27 | AopHelper.class,
28 | IocHelper.class,
29 | PluginHelper.class,
30 | };
31 | // 按照顺序加载类
32 | for (Class> cls : classList) {
33 | ClassUtil.loadClass(cls.getName());
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/InstanceFactory.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework;
2 |
3 | import java.util.Map;
4 | import java.util.concurrent.ConcurrentHashMap;
5 | import org.smart4j.framework.core.ClassScanner;
6 | import org.smart4j.framework.core.ConfigHelper;
7 | import org.smart4j.framework.core.impl.DefaultClassScanner;
8 | import org.smart4j.framework.dao.DataAccessor;
9 | import org.smart4j.framework.dao.impl.DefaultDataAccessor;
10 | import org.smart4j.framework.ds.DataSourceFactory;
11 | import org.smart4j.framework.ds.impl.DefaultDataSourceFactory;
12 | import org.smart4j.framework.mvc.HandlerExceptionResolver;
13 | import org.smart4j.framework.mvc.HandlerInvoker;
14 | import org.smart4j.framework.mvc.HandlerMapping;
15 | import org.smart4j.framework.mvc.ViewResolver;
16 | import org.smart4j.framework.mvc.impl.DefaultHandlerExceptionResolver;
17 | import org.smart4j.framework.mvc.impl.DefaultHandlerInvoker;
18 | import org.smart4j.framework.mvc.impl.DefaultHandlerMapping;
19 | import org.smart4j.framework.mvc.impl.DefaultViewResolver;
20 | import org.smart4j.framework.util.ObjectUtil;
21 | import org.smart4j.framework.util.StringUtil;
22 |
23 | /**
24 | * 实例工厂
25 | *
26 | * @author huangyong
27 | * @since 2.3
28 | */
29 | public class InstanceFactory {
30 |
31 | /**
32 | * 用于缓存对应的实例
33 | */
34 | private static final Map cache = new ConcurrentHashMap();
35 |
36 | /**
37 | * ClassScanner
38 | */
39 | private static final String CLASS_SCANNER = "smart.framework.custom.class_scanner";
40 |
41 | /**
42 | * DataSourceFactory
43 | */
44 | private static final String DS_FACTORY = "smart.framework.custom.ds_factory";
45 |
46 | /**
47 | * DataAccessor
48 | */
49 | private static final String DATA_ACCESSOR = "smart.framework.custom.data_accessor";
50 |
51 | /**
52 | * HandlerMapping
53 | */
54 | private static final String HANDLER_MAPPING = "smart.framework.custom.handler_mapping";
55 |
56 | /**
57 | * HandlerInvoker
58 | */
59 | private static final String HANDLER_INVOKER = "smart.framework.custom.handler_invoker";
60 |
61 | /**
62 | * HandlerExceptionResolver
63 | */
64 | private static final String HANDLER_EXCEPTION_RESOLVER = "smart.framework.custom.handler_exception_resolver";
65 |
66 | /**
67 | * ViewResolver
68 | */
69 | private static final String VIEW_RESOLVER = "smart.framework.custom.view_resolver";
70 |
71 | /**
72 | * 获取 ClassScanner
73 | */
74 | public static ClassScanner getClassScanner() {
75 | return getInstance(CLASS_SCANNER, DefaultClassScanner.class);
76 | }
77 |
78 | /**
79 | * 获取 DataSourceFactory
80 | */
81 | public static DataSourceFactory getDataSourceFactory() {
82 | return getInstance(DS_FACTORY, DefaultDataSourceFactory.class);
83 | }
84 |
85 | /**
86 | * 获取 DataAccessor
87 | */
88 | public static DataAccessor getDataAccessor() {
89 | return getInstance(DATA_ACCESSOR, DefaultDataAccessor.class);
90 | }
91 |
92 | /**
93 | * 获取 HandlerMapping
94 | */
95 | public static HandlerMapping getHandlerMapping() {
96 | return getInstance(HANDLER_MAPPING, DefaultHandlerMapping.class);
97 | }
98 |
99 | /**
100 | * 获取 HandlerInvoker
101 | */
102 | public static HandlerInvoker getHandlerInvoker() {
103 | return getInstance(HANDLER_INVOKER, DefaultHandlerInvoker.class);
104 | }
105 |
106 | /**
107 | * 获取 HandlerExceptionResolver
108 | */
109 | public static HandlerExceptionResolver getHandlerExceptionResolver() {
110 | return getInstance(HANDLER_EXCEPTION_RESOLVER, DefaultHandlerExceptionResolver.class);
111 | }
112 |
113 | /**
114 | * 获取 ViewResolver
115 | */
116 | public static ViewResolver getViewResolver() {
117 | return getInstance(VIEW_RESOLVER, DefaultViewResolver.class);
118 | }
119 |
120 | @SuppressWarnings("unchecked")
121 | public static T getInstance(String cacheKey, Class defaultImplClass) {
122 | // 若缓存中存在对应的实例,则返回该实例
123 | if (cache.containsKey(cacheKey)) {
124 | return (T) cache.get(cacheKey);
125 | }
126 | // 从配置文件中获取相应的接口实现类配置
127 | String implClassName = ConfigHelper.getString(cacheKey);
128 | // 若实现类配置不存在,则使用默认实现类
129 | if (StringUtil.isEmpty(implClassName)) {
130 | implClassName = defaultImplClass.getName();
131 | }
132 | // 通过反射创建该实现类对应的实例
133 | T instance = ObjectUtil.newInstance(implClassName);
134 | // 若该实例不为空,则将其放入缓存
135 | if (instance != null) {
136 | cache.put(cacheKey, instance);
137 | }
138 | // 返回该实例
139 | return instance;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/AopHelper.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.util.ArrayList;
5 | import java.util.Collections;
6 | import java.util.Comparator;
7 | import java.util.HashMap;
8 | import java.util.LinkedHashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 | import org.smart4j.framework.FrameworkConstant;
12 | import org.smart4j.framework.InstanceFactory;
13 | import org.smart4j.framework.aop.annotation.Aspect;
14 | import org.smart4j.framework.aop.annotation.AspectOrder;
15 | import org.smart4j.framework.aop.proxy.Proxy;
16 | import org.smart4j.framework.aop.proxy.ProxyManager;
17 | import org.smart4j.framework.core.ClassHelper;
18 | import org.smart4j.framework.core.ClassScanner;
19 | import org.smart4j.framework.core.fault.InitializationError;
20 | import org.smart4j.framework.ioc.BeanHelper;
21 | import org.smart4j.framework.plugin.PluginProxy;
22 | import org.smart4j.framework.tx.TransactionProxy;
23 | import org.smart4j.framework.tx.annotation.Service;
24 | import org.smart4j.framework.util.ClassUtil;
25 | import org.smart4j.framework.util.CollectionUtil;
26 | import org.smart4j.framework.util.StringUtil;
27 |
28 | /**
29 | * 初始化 AOP 框架
30 | *
31 | * @author huangyong
32 | * @since 1.0
33 | */
34 | public class AopHelper {
35 |
36 | /**
37 | * 获取 ClassScanner
38 | */
39 | private static final ClassScanner classScanner = InstanceFactory.getClassScanner();
40 |
41 | static {
42 | try {
43 | // 创建 Proxy Map(用于 存放代理类 与 目标类列表 的映射关系)
44 | Map, List>> proxyMap = createProxyMap();
45 | // 创建 Target Map(用于 存放目标类 与 代理类列表 的映射关系)
46 | Map, List> targetMap = createTargetMap(proxyMap);
47 | // 遍历 Target Map
48 | for (Map.Entry, List> targetEntry : targetMap.entrySet()) {
49 | // 分别获取 map 中的 key 与 value
50 | Class> targetClass = targetEntry.getKey();
51 | List proxyList = targetEntry.getValue();
52 | // 创建代理实例
53 | Object proxyInstance = ProxyManager.createProxy(targetClass, proxyList);
54 | // 用代理实例覆盖目标实例,并放入 Bean 容器中
55 | BeanHelper.setBean(targetClass, proxyInstance);
56 | }
57 | } catch (Exception e) {
58 | throw new InitializationError("初始化 AopHelper 出错!", e);
59 | }
60 | }
61 |
62 | private static Map, List>> createProxyMap() throws Exception {
63 | Map, List>> proxyMap = new LinkedHashMap, List>>();
64 | // 添加相关代理
65 | addPluginProxy(proxyMap); // 插件代理
66 | addAspectProxy(proxyMap); // 切面代理
67 | addTransactionProxy(proxyMap); // 事务代理
68 | return proxyMap;
69 | }
70 |
71 | private static void addPluginProxy(Map, List>> proxyMap) throws Exception {
72 | // 获取插件包名下父类为 PluginProxy 的所有类(插件代理类)
73 | List> pluginProxyClassList = classScanner.getClassListBySuper(FrameworkConstant.PLUGIN_PACKAGE, PluginProxy.class);
74 | if (CollectionUtil.isNotEmpty(pluginProxyClassList)) {
75 | // 遍历所有插件代理类
76 | for (Class> pluginProxyClass : pluginProxyClassList) {
77 | // 创建插件代理类实例
78 | PluginProxy pluginProxy = (PluginProxy) pluginProxyClass.newInstance();
79 | // 将插件代理类及其所对应的目标类列表放入 Proxy Map 中
80 | proxyMap.put(pluginProxyClass, pluginProxy.getTargetClassList());
81 | }
82 | }
83 | }
84 |
85 | private static void addAspectProxy(Map, List>> proxyMap) throws Exception {
86 | // 获取切面类(所有继承于 BaseAspect 的类)
87 | List> aspectProxyClassList = ClassHelper.getClassListBySuper(AspectProxy.class);
88 | // 添加插件包下所有的切面类
89 | aspectProxyClassList.addAll(classScanner.getClassListBySuper(FrameworkConstant.PLUGIN_PACKAGE, AspectProxy.class));
90 | // 排序切面类
91 | sortAspectProxyClassList(aspectProxyClassList);
92 | // 遍历切面类
93 | for (Class> aspectProxyClass : aspectProxyClassList) {
94 | // 判断 Aspect 注解是否存在
95 | if (aspectProxyClass.isAnnotationPresent(Aspect.class)) {
96 | // 获取 Aspect 注解
97 | Aspect aspect = aspectProxyClass.getAnnotation(Aspect.class);
98 | // 创建目标类列表
99 | List> targetClassList = createTargetClassList(aspect);
100 | // 初始化 Proxy Map
101 | proxyMap.put(aspectProxyClass, targetClassList);
102 | }
103 | }
104 | }
105 |
106 | private static void addTransactionProxy(Map, List>> proxyMap) {
107 | // 使用 TransactionProxy 代理所有 Service 类
108 | List> serviceClassList = ClassHelper.getClassListByAnnotation(Service.class);
109 | proxyMap.put(TransactionProxy.class, serviceClassList);
110 | }
111 |
112 | private static void sortAspectProxyClassList(List> proxyClassList) {
113 | // 排序代理类列表
114 | Collections.sort(proxyClassList, new Comparator>() {
115 | @Override
116 | public int compare(Class> aspect1, Class> aspect2) {
117 | if (aspect1.isAnnotationPresent(AspectOrder.class) || aspect2.isAnnotationPresent(AspectOrder.class)) {
118 | // 若有 Order 注解,则优先比较(序号的值越小越靠前)
119 | if (aspect1.isAnnotationPresent(AspectOrder.class)) {
120 | return getOrderValue(aspect1) - getOrderValue(aspect2);
121 | } else {
122 | return getOrderValue(aspect2) - getOrderValue(aspect1);
123 | }
124 | } else {
125 | // 若无 Order 注解,则比较类名(按字母顺序升序排列)
126 | return aspect1.hashCode() - aspect2.hashCode();
127 | }
128 | }
129 |
130 | private int getOrderValue(Class> aspect) {
131 | return aspect.getAnnotation(AspectOrder.class) != null ? aspect.getAnnotation(AspectOrder.class).value() : 0;
132 | }
133 | });
134 | }
135 |
136 | private static List> createTargetClassList(Aspect aspect) throws Exception {
137 | List> targetClassList = new ArrayList>();
138 | // 获取 Aspect 注解的相关属性
139 | String pkg = aspect.pkg();
140 | String cls = aspect.cls();
141 | Class extends Annotation> annotation = aspect.annotation();
142 | // 若包名不为空,则需进一步判断类名是否为空
143 | if (StringUtil.isNotEmpty(pkg)) {
144 | if (StringUtil.isNotEmpty(cls)) {
145 | // 若类名不为空,则仅添加该类
146 | targetClassList.add(ClassUtil.loadClass(pkg + "." + cls, false));
147 | } else {
148 | // 若注解不为空且不是 Aspect 注解,则添加指定包名下带有该注解的所有类
149 | if (annotation != null && !annotation.equals(Aspect.class)) {
150 | targetClassList.addAll(classScanner.getClassListByAnnotation(pkg, annotation));
151 | } else {
152 | // 否则添加该包名下所有类
153 | targetClassList.addAll(classScanner.getClassList(pkg));
154 | }
155 | }
156 | } else {
157 | // 若注解不为空且不是 Aspect 注解,则添加应用包名下带有该注解的所有类
158 | if (annotation != null && !annotation.equals(Aspect.class)) {
159 | targetClassList.addAll(ClassHelper.getClassListByAnnotation(annotation));
160 | }
161 | }
162 | return targetClassList;
163 | }
164 |
165 | private static Map, List> createTargetMap(Map, List>> proxyMap) throws Exception {
166 | Map, List> targetMap = new HashMap, List>();
167 | // 遍历 Proxy Map
168 | for (Map.Entry, List>> proxyEntry : proxyMap.entrySet()) {
169 | // 分别获取 map 中的 key 与 value
170 | Class> proxyClass = proxyEntry.getKey();
171 | List> targetClassList = proxyEntry.getValue();
172 | // 遍历目标类列表
173 | for (Class> targetClass : targetClassList) {
174 | // 创建代理类(切面类)实例
175 | Proxy baseAspect = (Proxy) proxyClass.newInstance();
176 | // 初始化 Target Map
177 | if (targetMap.containsKey(targetClass)) {
178 | targetMap.get(targetClass).add(baseAspect);
179 | } else {
180 | List baseAspectList = new ArrayList();
181 | baseAspectList.add(baseAspect);
182 | targetMap.put(targetClass, baseAspectList);
183 | }
184 | }
185 | }
186 | return targetMap;
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/AspectProxy.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop;
2 |
3 | import java.lang.reflect.Method;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.smart4j.framework.aop.proxy.Proxy;
7 | import org.smart4j.framework.aop.proxy.ProxyChain;
8 |
9 | /**
10 | * 切面代理
11 | *
12 | * @author huangyong
13 | * @since 2.0
14 | */
15 | public abstract class AspectProxy implements Proxy {
16 |
17 | private static final Logger logger = LoggerFactory.getLogger(AspectProxy.class);
18 |
19 | @Override
20 | public final Object doProxy(ProxyChain proxyChain) throws Throwable {
21 | Object result = null;
22 |
23 | Class> cls = proxyChain.getTargetClass();
24 | Method method = proxyChain.getTargetMethod();
25 | Object[] params = proxyChain.getMethodParams();
26 |
27 | begin();
28 | try {
29 | if (intercept(cls, method, params)) {
30 | before(cls, method, params);
31 | result = proxyChain.doProxyChain();
32 | after(cls, method, params, result);
33 | } else {
34 | result = proxyChain.doProxyChain();
35 | }
36 | } catch (Exception e) {
37 | logger.error("AOP 异常", e);
38 | error(cls, method, params, e);
39 | throw e;
40 | } finally {
41 | end();
42 | }
43 |
44 | return result;
45 | }
46 |
47 | public void begin() {
48 | }
49 |
50 | public boolean intercept(Class> cls, Method method, Object[] params) throws Throwable {
51 | return true;
52 | }
53 |
54 | public void before(Class> cls, Method method, Object[] params) throws Throwable {
55 | }
56 |
57 | public void after(Class> cls, Method method, Object[] params, Object result) throws Throwable {
58 | }
59 |
60 | public void error(Class> cls, Method method, Object[] params, Throwable e) {
61 | }
62 |
63 | public void end() {
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/annotation/Aspect.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop.annotation;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * 定义切面类
11 | *
12 | * @author huangyong
13 | * @since 1.0
14 | */
15 | @Target(ElementType.TYPE)
16 | @Retention(RetentionPolicy.RUNTIME)
17 | public @interface Aspect {
18 |
19 | /**
20 | * 包名
21 | */
22 | String pkg() default "";
23 |
24 | /**
25 | * 类名
26 | */
27 | String cls() default "";
28 |
29 | /**
30 | * 注解
31 | *
32 | * @since 2.2
33 | */
34 | Class extends Annotation> annotation() default Aspect.class;
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/annotation/AspectOrder.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * 定义切面顺序
10 | *
11 | * @author huangyong
12 | * @since 1.0
13 | */
14 | @Target(ElementType.TYPE)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface AspectOrder {
17 |
18 | int value();
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/proxy/Proxy.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop.proxy;
2 |
3 | /**
4 | * 代理接口
5 | *
6 | * @author huangyong
7 | * @since 2.0
8 | */
9 | public interface Proxy {
10 |
11 | /**
12 | * 执行链式代理
13 | *
14 | * @param proxyChain 代理链
15 | * @return 目标方法返回值
16 | * @throws Throwable 异常
17 | */
18 | Object doProxy(ProxyChain proxyChain) throws Throwable;
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/proxy/ProxyChain.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop.proxy;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import net.sf.cglib.proxy.MethodProxy;
7 |
8 | /**
9 | * 代理链
10 | *
11 | * @author huangyong
12 | * @since 2.0
13 | */
14 | public class ProxyChain {
15 |
16 | private final Class> targetClass;
17 | private final Object targetObject;
18 | private final Method targetMethod;
19 | private final MethodProxy methodProxy;
20 | private final Object[] methodParams;
21 |
22 | private List proxyList = new ArrayList();
23 | private int proxyIndex = 0;
24 |
25 | public ProxyChain(Class> targetClass, Object targetObject, Method targetMethod, MethodProxy methodProxy, Object[] methodParams, List proxyList) {
26 | this.targetClass = targetClass;
27 | this.targetObject = targetObject;
28 | this.targetMethod = targetMethod;
29 | this.methodProxy = methodProxy;
30 | this.methodParams = methodParams;
31 | this.proxyList = proxyList;
32 | }
33 |
34 | public Object[] getMethodParams() {
35 | return methodParams;
36 | }
37 |
38 | public Class> getTargetClass() {
39 | return targetClass;
40 | }
41 |
42 | public Method getTargetMethod() {
43 | return targetMethod;
44 | }
45 |
46 | public Object doProxyChain() throws Throwable {
47 | Object methodResult;
48 | if (proxyIndex < proxyList.size()) {
49 | methodResult = proxyList.get(proxyIndex++).doProxy(this);
50 | } else {
51 | methodResult = methodProxy.invokeSuper(targetObject, methodParams);
52 | }
53 | return methodResult;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/aop/proxy/ProxyManager.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.aop.proxy;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.List;
5 | import net.sf.cglib.proxy.Enhancer;
6 | import net.sf.cglib.proxy.MethodInterceptor;
7 | import net.sf.cglib.proxy.MethodProxy;
8 |
9 | /**
10 | * 代理管理器
11 | *
12 | * @author huangyong
13 | * @since 2.0
14 | */
15 | public class ProxyManager {
16 |
17 | @SuppressWarnings("unchecked")
18 | public static T createProxy(final Class> targetClass, final List proxyList) {
19 | return (T) Enhancer.create(targetClass, new MethodInterceptor() {
20 | @Override
21 | public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {
22 | return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();
23 | }
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/ClassHelper.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.util.List;
5 | import org.smart4j.framework.InstanceFactory;
6 |
7 | /**
8 | * 根据条件获取相关类
9 | *
10 | * @author huangyong
11 | * @since 1.0
12 | */
13 | public class ClassHelper {
14 |
15 | /**
16 | * 获取基础包名
17 | */
18 | private static final String basePackage = ConfigHelper.getString("smart.framework.app.base_package");
19 |
20 | /**
21 | * 获取 ClassScanner
22 | */
23 | private static final ClassScanner classScanner = InstanceFactory.getClassScanner();
24 |
25 | /**
26 | * 获取基础包名中的所有类
27 | */
28 | public static List> getClassList() {
29 | return classScanner.getClassList(basePackage);
30 | }
31 |
32 | /**
33 | * 获取基础包名中指定父类或接口的相关类
34 | */
35 | public static List> getClassListBySuper(Class> superClass) {
36 | return classScanner.getClassListBySuper(basePackage, superClass);
37 | }
38 |
39 | /**
40 | * 获取基础包名中指定注解的相关类
41 | */
42 | public static List> getClassListByAnnotation(Class extends Annotation> annotationClass) {
43 | return classScanner.getClassListByAnnotation(basePackage, annotationClass);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/ClassScanner.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.util.List;
5 |
6 | /**
7 | * 类扫描器
8 | *
9 | * @author huangyong
10 | * @since 2.3
11 | */
12 | public interface ClassScanner {
13 |
14 | /**
15 | * 获取指定包名中的所有类
16 | */
17 | List> getClassList(String packageName);
18 |
19 | /**
20 | * 获取指定包名中指定注解的相关类
21 | */
22 | List> getClassListByAnnotation(String packageName, Class extends Annotation> annotationClass);
23 |
24 | /**
25 | * 获取指定包名中指定父类或接口的相关类
26 | */
27 | List> getClassListBySuper(String packageName, Class> superClass);
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/ConfigHelper.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core;
2 |
3 | import java.util.Map;
4 | import java.util.Properties;
5 | import org.smart4j.framework.FrameworkConstant;
6 | import org.smart4j.framework.util.PropsUtil;
7 |
8 | /**
9 | * 获取属性文件中的属性值
10 | *
11 | * @author huangyong
12 | * @since 1.0
13 | */
14 | public class ConfigHelper {
15 |
16 | /**
17 | * 属性文件对象
18 | */
19 | private static final Properties configProps = PropsUtil.loadProps(FrameworkConstant.CONFIG_PROPS);
20 |
21 | /**
22 | * 获取 String 类型的属性值
23 | */
24 | public static String getString(String key) {
25 | return PropsUtil.getString(configProps, key);
26 | }
27 |
28 | /**
29 | * 获取 String 类型的属性值(可指定默认值)
30 | */
31 | public static String getString(String key, String defaultValue) {
32 | return PropsUtil.getString(configProps, key, defaultValue);
33 | }
34 |
35 | /**
36 | * 获取 int 类型的属性值
37 | */
38 | public static int getInt(String key) {
39 | return PropsUtil.getNumber(configProps, key);
40 | }
41 |
42 | /**
43 | * 获取 int 类型的属性值(可指定默认值)
44 | */
45 | public static int getInt(String key, int defaultValue) {
46 | return PropsUtil.getNumber(configProps, key, defaultValue);
47 | }
48 |
49 | /**
50 | * 获取 boolean 类型的属性值
51 | */
52 | public static boolean getBoolean(String key) {
53 | return PropsUtil.getBoolean(configProps, key);
54 | }
55 |
56 | /**
57 | * 获取 int 类型的属性值(可指定默认值)
58 | */
59 | public static boolean getBoolean(String key, boolean defaultValue) {
60 | return PropsUtil.getBoolean(configProps, key, defaultValue);
61 | }
62 |
63 | /**
64 | * 获取指定前缀的相关属性
65 | *
66 | * @since 2.2
67 | */
68 | public static Map getMap(String prefix) {
69 | return PropsUtil.getMap(configProps, prefix);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/bean/BaseBean.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.bean;
2 |
3 | import java.io.Serializable;
4 | import org.apache.commons.lang.builder.EqualsBuilder;
5 | import org.apache.commons.lang.builder.HashCodeBuilder;
6 | import org.apache.commons.lang.builder.ToStringBuilder;
7 | import org.apache.commons.lang.builder.ToStringStyle;
8 |
9 | /**
10 | * 提供 Bean 类的基础特性
11 | *
12 | * @author huangyong
13 | * @since 1.0
14 | */
15 | public abstract class BaseBean implements Serializable {
16 |
17 | @Override
18 | public int hashCode() {
19 | return HashCodeBuilder.reflectionHashCode(this);
20 | }
21 |
22 | @Override
23 | public boolean equals(Object obj) {
24 | return EqualsBuilder.reflectionEquals(this, obj);
25 | }
26 |
27 | @Override
28 | public String toString() {
29 | return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/fault/InitializationError.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.fault;
2 |
3 | /**
4 | * 初始化错误
5 | *
6 | * @author huangyong
7 | * @since 2.2
8 | */
9 | public class InitializationError extends Error {
10 |
11 | public InitializationError() {
12 | super();
13 | }
14 |
15 | public InitializationError(String message) {
16 | super(message);
17 | }
18 |
19 | public InitializationError(String message, Throwable cause) {
20 | super(message, cause);
21 | }
22 |
23 | public InitializationError(Throwable cause) {
24 | super(cause);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/impl/DefaultClassScanner.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.impl;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.util.List;
5 | import org.smart4j.framework.core.ClassScanner;
6 | import org.smart4j.framework.core.impl.support.AnnotationClassTemplate;
7 | import org.smart4j.framework.core.impl.support.ClassTemplate;
8 | import org.smart4j.framework.core.impl.support.SupperClassTemplate;
9 |
10 | /**
11 | * 默认类扫描器
12 | *
13 | * @author huangyong
14 | * @since 2.3
15 | */
16 | public class DefaultClassScanner implements ClassScanner {
17 |
18 | @Override
19 | public List> getClassList(String packageName) {
20 | return new ClassTemplate(packageName) {
21 | @Override
22 | public boolean checkAddClass(Class> cls) {
23 | String className = cls.getName();
24 | String pkgName = className.substring(0, className.lastIndexOf("."));
25 | return pkgName.startsWith(packageName);
26 | }
27 | }.getClassList();
28 | }
29 |
30 | @Override
31 | public List> getClassListByAnnotation(String packageName, Class extends Annotation> annotationClass) {
32 | return new AnnotationClassTemplate(packageName, annotationClass) {
33 | @Override
34 | public boolean checkAddClass(Class> cls) {
35 | return cls.isAnnotationPresent(annotationClass);
36 | }
37 | }.getClassList();
38 | }
39 |
40 | @Override
41 | public List> getClassListBySuper(String packageName, Class> superClass) {
42 | return new SupperClassTemplate(packageName, superClass) {
43 | @Override
44 | public boolean checkAddClass(Class> cls) {
45 | return superClass.isAssignableFrom(cls) && !superClass.equals(cls);
46 | }
47 | }.getClassList();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/impl/support/AnnotationClassTemplate.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.impl.support;
2 |
3 | import java.lang.annotation.Annotation;
4 |
5 | /**
6 | * 用于获取注解类的模板类
7 | *
8 | * @author huangyong
9 | * @since 2.3
10 | */
11 | public abstract class AnnotationClassTemplate extends ClassTemplate {
12 |
13 | protected final Class extends Annotation> annotationClass;
14 |
15 | protected AnnotationClassTemplate(String packageName, Class extends Annotation> annotationClass) {
16 | super(packageName);
17 | this.annotationClass = annotationClass;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/impl/support/ClassTemplate.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.impl.support;
2 |
3 | import java.io.File;
4 | import java.io.FileFilter;
5 | import java.net.JarURLConnection;
6 | import java.net.URL;
7 | import java.util.ArrayList;
8 | import java.util.Enumeration;
9 | import java.util.List;
10 | import java.util.jar.JarEntry;
11 | import java.util.jar.JarFile;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.smart4j.framework.util.ClassUtil;
15 | import org.smart4j.framework.util.StringUtil;
16 |
17 | /**
18 | * 用于获取类的模板类
19 | *
20 | * @author huangyong
21 | * @since 2.3
22 | */
23 | public abstract class ClassTemplate {
24 |
25 | private static final Logger logger = LoggerFactory.getLogger(ClassTemplate.class);
26 |
27 | protected final String packageName;
28 |
29 | protected ClassTemplate(String packageName) {
30 | this.packageName = packageName;
31 | }
32 |
33 | public final List> getClassList() {
34 | List> classList = new ArrayList>();
35 | try {
36 | // 从包名获取 URL 类型的资源
37 | Enumeration urls = ClassUtil.getClassLoader().getResources(packageName.replace(".", "/"));
38 | // 遍历 URL 资源
39 | while (urls.hasMoreElements()) {
40 | URL url = urls.nextElement();
41 | if (url != null) {
42 | // 获取协议名(分为 file 与 jar)
43 | String protocol = url.getProtocol();
44 | if (protocol.equals("file")) {
45 | // 若在 class 目录中,则执行添加类操作
46 | String packagePath = url.getPath().replaceAll("%20", " ");
47 | addClass(classList, packagePath, packageName);
48 | } else if (protocol.equals("jar")) {
49 | // 若在 jar 包中,则解析 jar 包中的 entry
50 | JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
51 | JarFile jarFile = jarURLConnection.getJarFile();
52 | Enumeration jarEntries = jarFile.entries();
53 | while (jarEntries.hasMoreElements()) {
54 | JarEntry jarEntry = jarEntries.nextElement();
55 | String jarEntryName = jarEntry.getName();
56 | // 判断该 entry 是否为 class
57 | if (jarEntryName.endsWith(".class")) {
58 | // 获取类名
59 | String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
60 | // 执行添加类操作
61 | doAddClass(classList, className);
62 | }
63 | }
64 | }
65 | }
66 | }
67 | } catch (Exception e) {
68 | logger.error("获取类出错!", e);
69 | }
70 | return classList;
71 | }
72 |
73 | private void addClass(List> classList, String packagePath, String packageName) {
74 | try {
75 | // 获取包名路径下的 class 文件或目录
76 | File[] files = new File(packagePath).listFiles(new FileFilter() {
77 | @Override
78 | public boolean accept(File file) {
79 | return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
80 | }
81 | });
82 | // 遍历文件或目录
83 | for (File file : files) {
84 | String fileName = file.getName();
85 | // 判断是否为文件或目录
86 | if (file.isFile()) {
87 | // 获取类名
88 | String className = fileName.substring(0, fileName.lastIndexOf("."));
89 | if (StringUtil.isNotEmpty(packageName)) {
90 | className = packageName + "." + className;
91 | }
92 | // 执行添加类操作
93 | doAddClass(classList, className);
94 | } else {
95 | // 获取子包
96 | String subPackagePath = fileName;
97 | if (StringUtil.isNotEmpty(packagePath)) {
98 | subPackagePath = packagePath + "/" + subPackagePath;
99 | }
100 | // 子包名
101 | String subPackageName = fileName;
102 | if (StringUtil.isNotEmpty(packageName)) {
103 | subPackageName = packageName + "." + subPackageName;
104 | }
105 | // 递归调用
106 | addClass(classList, subPackagePath, subPackageName);
107 | }
108 | }
109 | } catch (Exception e) {
110 | logger.error("添加类出错!", e);
111 | }
112 | }
113 |
114 | private void doAddClass(List> classList, String className) {
115 | // 加载类
116 | Class> cls = ClassUtil.loadClass(className, false);
117 | // 判断是否可以添加类
118 | if (checkAddClass(cls)) {
119 | // 添加类
120 | classList.add(cls);
121 | }
122 | }
123 |
124 | /**
125 | * 验证是否允许添加类
126 | */
127 | public abstract boolean checkAddClass(Class> cls);
128 | }
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/core/impl/support/SupperClassTemplate.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.core.impl.support;
2 |
3 | /**
4 | * 用于获取子类的模板类
5 | *
6 | * @author huangyong
7 | * @since 2.3
8 | */
9 | public abstract class SupperClassTemplate extends ClassTemplate {
10 |
11 | protected final Class> superClass;
12 |
13 | protected SupperClassTemplate(String packageName, Class> superClass) {
14 | super(packageName);
15 | this.superClass = superClass;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/org/smart4j/framework/dao/DataAccessor.java:
--------------------------------------------------------------------------------
1 | package org.smart4j.framework.dao;
2 |
3 | import java.io.Serializable;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | /**
8 | * 数据访问器
9 | *
10 | * @author huangyong
11 | * @since 2.3
12 | */
13 | public interface DataAccessor {
14 |
15 | /**
16 | * 查询对应的实体,返回单条记录
17 | */
18 | T queryEntity(Class entityClass, String sql, Object... params);
19 |
20 | /**
21 | * 查询对应的实体列表,返回多条记录
22 | */
23 | List queryEntityList(Class entityClass, String sql, Object... params);
24 |
25 | /**
26 | * 查询对应的实体列表,返回单条记录(主键 => 实体)
27 | */
28 | Map queryEntityMap(Class entityClass, String sql, Object... params);
29 |
30 | /**
31 | * 查询对应的数据,返回单条记录
32 | */
33 | Object[] queryArray(String sql, Object... params);
34 |
35 | /**
36 | * 查询对应的数据,返回多条记录
37 | */
38 | List