mirror of
https://github.com/wahyd4/Martian.git
synced 2026-08-09 05:16:21 +10:00
首次提交
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
Apache License
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
@@ -186,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2018 俞晔
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -198,4 +199,4 @@
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
limitations under the License.
|
||||
@@ -1 +1,83 @@
|
||||
# Mars-java
|
||||
<h1 align="center">Java Web development framework that does not require a container</h1>
|
||||
|
||||
<p align="center"><img width="400px" src="https://images.gitee.com/uploads/images/2019/0113/190655_bcd43f13_2331383.png" /></p>
|
||||
|
||||
<br/>
|
||||
|
||||
<h2>Introduction to the framework</h2>
|
||||
|
||||
<p>First of all, thanks to mybatis, fastjson, cglib, pagehelper, druid, jwt, jyaml, netty, hutool. Because of the integration of these open source projects, my framework can be developed smoothly.</p>
|
||||
|
||||
<p>Goge-framework is a java development framework that mimics springboot. It supports functions similar to springboot: AOP, IOC, MVC also integrates mybatis as a persistence layer. Unlike springboot it is:</p>
|
||||
|
||||
<p>
|
||||
|
||||
1. This framework uses netty as the http service
|
||||
<br/>
|
||||
|
||||
2. Session management with JWT
|
||||
<br/>
|
||||
|
||||
3. Only support the main method to start, can not play the war package
|
||||
<br/>
|
||||
|
||||
4. Controller can only return json, does not support forwarding and redirection
|
||||
</p>
|
||||
|
||||
<h2>Document</h2>
|
||||
|
||||
[Document](http://goge-framework.com/doc.html)
|
||||
|
||||
<h2>Extension package</h2>
|
||||
|
||||
<p>Support redis connection</p>
|
||||
|
||||
<p>Encapsulated mail delivery, MD5, AES and other tools class</p>
|
||||
|
||||
[Extension package](https://github.com/yuyenews/Goge-extends)
|
||||
|
||||
<h2>Project structure</h2>
|
||||
|
||||
<p>Red module is temporarily unavailable</p>
|
||||
<p><img src="http://goge-framework.com/img/jiagou.png"/></p>
|
||||
|
||||
<h2>Simple contrast</h2>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr class="firstRow">
|
||||
<td>name</td>
|
||||
<td>AOP</td>
|
||||
<td>IOC</td>
|
||||
<td>MVC</td>
|
||||
<td>mybatis</td>
|
||||
<td>configuration file</td>
|
||||
<td>startup method</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Goge</td>
|
||||
<td>support</td>
|
||||
<td>support</td>
|
||||
<td>support</td>
|
||||
<td>Direct integration</td>
|
||||
<td>Only need one</td>
|
||||
<td>main method</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Springboot</td>
|
||||
<td>support</td>
|
||||
<td>support</td>
|
||||
<td>support</td>
|
||||
<td>Can be integration</td>
|
||||
<td>Only need one</td>
|
||||
<td>main method,war+tomcat</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Contact</h2>
|
||||
|
||||
<p>If you have any questions, you can add my QQ group:773291321</p>
|
||||
|
||||
<p><img src="https://images.gitee.com/uploads/images/2018/1224/230844_a8755140_2331383.png"/></p>
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-aop</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.yuyenews.aop.base;
|
||||
|
||||
/**
|
||||
* AOP定义模板
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public interface BaseAop {
|
||||
|
||||
/**
|
||||
* 方法开始前调用
|
||||
* @param args 参数
|
||||
*/
|
||||
void startMethod(Object[] args);
|
||||
|
||||
/**
|
||||
* 方法结束后调用
|
||||
* @param args 参数
|
||||
*/
|
||||
void endMethod(Object[] args);
|
||||
|
||||
/**
|
||||
* 出异常后调用
|
||||
*/
|
||||
void exp(Throwable e);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.yuyenews.aop.proxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
/**
|
||||
* 代理类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class CglibProxy implements MethodInterceptor {
|
||||
|
||||
private Enhancer enhancer;
|
||||
|
||||
private Map<String,Class<?>> list;
|
||||
|
||||
/**
|
||||
* 获取代理对象
|
||||
* @param clazz bean的class
|
||||
* @param list aop类的class
|
||||
* @return 对象
|
||||
*/
|
||||
public Object getProxy(Class<?> clazz,Map<String,Class<?>> list) {
|
||||
|
||||
this.list = list;
|
||||
enhancer = new Enhancer();
|
||||
// 设置需要创建子类的类
|
||||
enhancer.setSuperclass(clazz);
|
||||
enhancer.setCallback(this);
|
||||
// 通过字节码技术动态创建子类实例
|
||||
return enhancer.create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绑定代理
|
||||
*/
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object obj = null;
|
||||
Class<?> c = list.get(method.getName());
|
||||
if(c != null){
|
||||
obj = c.getDeclaredConstructor().newInstance();
|
||||
Method m2 = c.getDeclaredMethod("startMethod",new Class[] {Object[].class});
|
||||
m2.invoke(obj,new Object[] {args});
|
||||
}
|
||||
|
||||
Object o1 = null;
|
||||
try {
|
||||
o1 = methodProxy.invokeSuper(o, args);
|
||||
|
||||
if(c != null){
|
||||
Method m3 = c.getDeclaredMethod("endMethod",new Class[] {Object[].class});
|
||||
m3.invoke(obj,new Object[] {args});
|
||||
}
|
||||
|
||||
return o1;
|
||||
} catch (Throwable e) {
|
||||
if(c != null){
|
||||
Method m4 = c.getDeclaredMethod("exp",new Class[] {Throwable.class});
|
||||
m4.invoke(obj,new Object[] {e});
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jyaml</groupId>
|
||||
<artifactId>jyaml</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.yuyenews.core.after;
|
||||
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 框架启动后立刻执行
|
||||
*/
|
||||
public class StartAfter {
|
||||
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 框架启动后立刻执行
|
||||
*/
|
||||
public static void after() throws Exception {
|
||||
try {
|
||||
Object objs = constants.getAttr(EasyConstant.EASYAFTERS);
|
||||
if(objs != null) {
|
||||
List<Class> easyLoads = (List<Class>)objs;
|
||||
|
||||
for(Class cls : easyLoads){
|
||||
Object obj = cls.getDeclaredConstructor().newInstance();
|
||||
Method method2 = cls.getDeclaredMethod("after");
|
||||
method2.invoke(obj);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Controller {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DataSource {
|
||||
|
||||
String value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyAfter {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyAop {
|
||||
|
||||
Class<?> className();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyAopType {
|
||||
|
||||
Class<?> className();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyBean {
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyDao {
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyInterceptor {
|
||||
String pattern() default "";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 加在controller的方法上 表示打印日志
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyLog {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.yuyenews.core.annotation.enums.RequestMetohd;
|
||||
|
||||
/**
|
||||
* 映射控制层方法的注解
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EasyMapping {
|
||||
|
||||
String value() default "";
|
||||
RequestMetohd method() default RequestMetohd.GET;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Resource {
|
||||
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yuyenews.core.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Traction {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.yuyenews.core.annotation.enums;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public enum RequestMetohd {
|
||||
|
||||
POST, GET, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yuyenews.core.base;
|
||||
|
||||
/**
|
||||
* 框架启动后立刻执行的类 必须实现这个接口
|
||||
*/
|
||||
public interface BaseAfter {
|
||||
|
||||
void after() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.yuyenews.core.constant;
|
||||
|
||||
/**
|
||||
* 框架常量
|
||||
*/
|
||||
public class EasyConstant {
|
||||
|
||||
/**
|
||||
* 本地配置文件
|
||||
*/
|
||||
public static final String CONFIG_PATH = "/goge.yml";
|
||||
/**
|
||||
* 所有的easyAfter类信息
|
||||
*/
|
||||
public static final String EASYAFTERS = "easyAfters";
|
||||
/**
|
||||
* 记录是否已经调用完createbean方法了
|
||||
*/
|
||||
public static final String HAS_START="hasStart";
|
||||
/**
|
||||
* 所有的controller类信息
|
||||
*/
|
||||
public static final String CONTROLLERS = "contorllers";
|
||||
/**
|
||||
* 所有的easyBeans类信息
|
||||
*/
|
||||
public static final String EASYBEANS = "easyBeans";
|
||||
/**
|
||||
* 所有的interceptors类信息
|
||||
*/
|
||||
public static final String INTERCEPTORS = "interceptors";
|
||||
/**
|
||||
* 所有的easyDaos类信息
|
||||
*/
|
||||
public static final String EASYDAOS = "easyDaos";
|
||||
|
||||
/**
|
||||
* 所有的controller对象
|
||||
*/
|
||||
public static final String CONTROLLER_OBJECTS = "controlObjects";
|
||||
|
||||
/**
|
||||
* 所有的bean对象,包括 easyBean和easydDao
|
||||
*/
|
||||
public static final String EASYBEAN_OBJECTS = "easyBeanObjects";
|
||||
|
||||
/**
|
||||
* 接受远程配置中心通知的controller
|
||||
*/
|
||||
public static final String REMOTE_CONFIG_CONTROLLER = "com.yuyenews.remote.config.RemoteConfigController";
|
||||
|
||||
/**
|
||||
* 读取远程配置的路径
|
||||
*/
|
||||
public static final String READ_REMOTE_CONFIG = "http://${0}/getConfig";
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.yuyenews.core.constant;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 全局存储空间
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasySpace {
|
||||
|
||||
private static EasySpace constants;
|
||||
|
||||
private Map<String, Object> map = new ConcurrentHashMap<>();
|
||||
|
||||
private EasySpace() {
|
||||
}
|
||||
|
||||
public static EasySpace getEasySpace() {
|
||||
if (constants == null) {
|
||||
constants = new EasySpace();
|
||||
}
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
||||
/**
|
||||
* 往Constants里添加数据
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void setAttr(String key,Object value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Constants里获取数据
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object getAttr(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除元素
|
||||
* @param key
|
||||
*/
|
||||
public void remove(String key) {
|
||||
map.remove(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.yuyenews.core.load;
|
||||
|
||||
import com.yuyenews.core.annotation.*;
|
||||
import com.yuyenews.core.util.ReadClass;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 获取项目中的所有class
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class LoadClass {
|
||||
|
||||
/**
|
||||
* 加载所有bean,包括controller 的class对象
|
||||
* @param packageName
|
||||
*/
|
||||
public static void loadBeans(String packageName) throws Exception{
|
||||
try {
|
||||
/* 加载本地bean */
|
||||
LoadNactive.loadNactiveBeans();
|
||||
|
||||
/* 加载框架用户的所有bean */
|
||||
loadAllBeans(packageName);
|
||||
} catch (Exception e){
|
||||
throw new Exception("加载bean出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载所有的bean,包括controller 的class对象
|
||||
* @param packageName bean所在的包名
|
||||
*/
|
||||
private static void loadAllBeans(String packageName) throws Exception {
|
||||
try {
|
||||
Set<String> classList = ReadClass.loadClassList(packageName);
|
||||
for (String str : classList) {
|
||||
Class<?> cls = Class.forName(str);
|
||||
Controller controller = cls.getAnnotation(Controller.class);
|
||||
EasyBean easyBean = cls.getAnnotation(EasyBean.class);
|
||||
EasyInterceptor easyInterceptor = cls.getAnnotation(EasyInterceptor.class);
|
||||
EasyDao easyDao = cls.getAnnotation(EasyDao.class);
|
||||
EasyAfter easyAfter = cls.getAnnotation(EasyAfter.class);
|
||||
|
||||
if(controller != null) {
|
||||
LoadNactive.loadController(cls, controller);
|
||||
}
|
||||
if(easyBean != null) {
|
||||
LoadNactive.loadEasyBean(cls, easyBean);
|
||||
}
|
||||
if(easyInterceptor != null){
|
||||
LoadNactive.loadInterceptor(cls,easyInterceptor);
|
||||
}
|
||||
if(easyDao != null){
|
||||
LoadNactive.loadDao(cls,easyDao);
|
||||
}
|
||||
if(easyAfter != null){
|
||||
LoadNactive.loadEasyAfter(cls);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new Exception("扫描["+packageName+"]包下的类发生错误",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.yuyenews.core.load;
|
||||
|
||||
import com.yuyenews.core.annotation.Controller;
|
||||
import com.yuyenews.core.annotation.EasyBean;
|
||||
import com.yuyenews.core.annotation.EasyDao;
|
||||
import com.yuyenews.core.annotation.EasyInterceptor;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 加载本地资源
|
||||
*/
|
||||
public class LoadNactive {
|
||||
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 加载本地bean
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void loadNactiveBeans() throws Exception {
|
||||
|
||||
/* 加载 接受远程配置中心通知的controller */
|
||||
Class<?> cls = Class.forName(EasyConstant.REMOTE_CONFIG_CONTROLLER);
|
||||
Controller controller = cls.getAnnotation(Controller.class);
|
||||
loadController(cls, controller);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将所有controller存到全局存储空间
|
||||
* @param cls
|
||||
* @param controller
|
||||
*/
|
||||
public static void loadController(Class<?> cls,Controller controller) {
|
||||
Object objs = constants.getAttr(EasyConstant.CONTROLLERS);
|
||||
List<Map<String,Object>> contorls = new ArrayList<>();
|
||||
if(objs != null) {
|
||||
contorls = (List<Map<String,Object>>)objs;
|
||||
}
|
||||
Map<String,Object> contorl = new HashMap<>();
|
||||
contorl.put("className", cls);
|
||||
contorl.put("annotation", controller);
|
||||
contorls.add(contorl);
|
||||
constants.setAttr(EasyConstant.CONTROLLERS, contorls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有easybean存到全局存储空间
|
||||
* @param cls
|
||||
* @param easyBean
|
||||
*/
|
||||
public static void loadEasyBean(Class<?> cls, EasyBean easyBean) {
|
||||
Object objs = constants.getAttr(EasyConstant.EASYBEANS);
|
||||
List<Map<String,Object>> easyBeans = new ArrayList<>();
|
||||
if(objs != null) {
|
||||
easyBeans = (List<Map<String,Object>>)objs;
|
||||
}
|
||||
Map<String,Object> eb = new HashMap<>();
|
||||
eb.put("className", cls);
|
||||
eb.put("annotation", easyBean);
|
||||
easyBeans.add(eb);
|
||||
constants.setAttr(EasyConstant.EASYBEANS, easyBeans);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有拦截器存到全局存储空间
|
||||
* @param cls
|
||||
* @param interceptor
|
||||
*/
|
||||
public static void loadInterceptor(Class<?> cls, EasyInterceptor interceptor){
|
||||
Object objs = constants.getAttr(EasyConstant.INTERCEPTORS);
|
||||
List<Map<String,Object>> interceptors = new ArrayList<>();
|
||||
if(objs != null) {
|
||||
interceptors = (List<Map<String,Object>>)objs;
|
||||
}
|
||||
Map<String,Object> eb = new HashMap<>();
|
||||
eb.put("className", cls);
|
||||
eb.put("annotation", interceptor);
|
||||
interceptors.add(eb);
|
||||
constants.setAttr(EasyConstant.INTERCEPTORS, interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载dao
|
||||
* @param cls
|
||||
* @param easyDao
|
||||
*/
|
||||
public static void loadDao(Class<?> cls, EasyDao easyDao){
|
||||
Object objs = constants.getAttr(EasyConstant.EASYDAOS);
|
||||
List<Map<String,Object>> easyDaos = new ArrayList<>();
|
||||
if(objs != null) {
|
||||
easyDaos = (List<Map<String,Object>>)objs;
|
||||
}
|
||||
Map<String,Object> eb = new HashMap<>();
|
||||
eb.put("className", cls);
|
||||
eb.put("annotation", easyDao);
|
||||
easyDaos.add(eb);
|
||||
constants.setAttr(EasyConstant.EASYDAOS, easyDaos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载easyAfter
|
||||
* @param cls
|
||||
*/
|
||||
public static void loadEasyAfter(Class<?> cls){
|
||||
Object objs = constants.getAttr(EasyConstant.EASYAFTERS);
|
||||
List<Class> easyLoads = new ArrayList<>();
|
||||
if(objs != null) {
|
||||
easyLoads = (List<Class>)objs;
|
||||
}
|
||||
easyLoads.add(cls);
|
||||
constants.setAttr(EasyConstant.EASYAFTERS, easyLoads);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.yuyenews.core.logger;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.logging.log4j.core.config.ConfigurationSource;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class GogeLog4jUtil {
|
||||
|
||||
/**
|
||||
* 加载log4j配置文件
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void initLog4jConfig(JSONObject config) throws Exception {
|
||||
String path = config.getString("logFile");
|
||||
if(path != null){
|
||||
if(path.startsWith("classPath-")){
|
||||
String logCfgPath = path.replace("classPath-","");
|
||||
InputStream inputStream = GogeLog4jUtil.class.getResourceAsStream("/"+logCfgPath);
|
||||
initLog4jPath(inputStream);
|
||||
} else {
|
||||
File file = new File(path);
|
||||
initLog4jPath(new FileInputStream(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载log4j配置文件
|
||||
* @param inputStream 文件流
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void initLog4jPath(InputStream inputStream) throws Exception {
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(inputStream);
|
||||
ConfigurationSource source = new ConfigurationSource(in);
|
||||
Configurator.initialize(null, source);
|
||||
|
||||
inputStream.close();
|
||||
in.close();
|
||||
} catch (Exception e){
|
||||
throw new Exception("logFile指向的路径下找不到相应的文件",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.yuyenews.core.logger;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
|
||||
public abstract class GogeLogger {
|
||||
|
||||
|
||||
public abstract void info(String info);
|
||||
|
||||
public abstract void warn(String info);
|
||||
|
||||
public abstract void error(String info,Throwable e);
|
||||
|
||||
public abstract void error(String info);
|
||||
|
||||
/**
|
||||
* 获取GogeLogger 对象
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static GogeLogger getLogger(Class cls){
|
||||
boolean str = hasLog4j();
|
||||
if(str){
|
||||
return new LoggerSlf4j(cls);
|
||||
}
|
||||
return new LoggerLog4j(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否使用了log4j
|
||||
* @return 布尔值
|
||||
*/
|
||||
private static boolean hasLog4j(){
|
||||
JSONObject config = ConfigUtil.getConfig();
|
||||
if(config == null){
|
||||
return true;
|
||||
}
|
||||
Object obj = config.get("logFile");
|
||||
return obj == null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.yuyenews.core.logger;
|
||||
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class LoggerLog4j extends GogeLogger {
|
||||
|
||||
private Logger logger;
|
||||
|
||||
public LoggerLog4j(Class cls){
|
||||
logger = LogManager.getLogger(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String info) {
|
||||
logger.info(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String info, Throwable e) {
|
||||
logger.error(info,e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String info) {
|
||||
logger.warn(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String info) {
|
||||
logger.error(info);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.yuyenews.core.logger;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LoggerSlf4j extends GogeLogger {
|
||||
|
||||
private Logger logger;
|
||||
|
||||
public LoggerSlf4j(Class cls){
|
||||
logger = LoggerFactory.getLogger(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String info) {
|
||||
logger.info(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String info, Throwable e) {
|
||||
logger.error(info,e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String info) {
|
||||
logger.warn(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String info) {
|
||||
logger.error(info);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yuyenews.core.model;
|
||||
|
||||
/**
|
||||
* easybean的实体类
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyBeanModel {
|
||||
|
||||
/**
|
||||
* bean名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* bean对象
|
||||
*/
|
||||
private Object obj;
|
||||
|
||||
/**
|
||||
* class对象
|
||||
*/
|
||||
private Class<?> cls;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Object getObj() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void setObj(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public void setCls(Class<?> cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.yuyenews.core.remote.config;
|
||||
|
||||
/**
|
||||
* 远程配置服务
|
||||
*/
|
||||
public class RemoteConfigService {
|
||||
|
||||
/**
|
||||
* 重新加载配置
|
||||
* @param config
|
||||
*
|
||||
* @return 加载结果
|
||||
*/
|
||||
public static String reloadConfig(Object config){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLog4jUtil;
|
||||
|
||||
/**
|
||||
* 配置文件工具类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ConfigUtil {
|
||||
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
|
||||
/**
|
||||
* 加载配置文件
|
||||
*/
|
||||
public static void loadConfig() throws Exception{
|
||||
try {
|
||||
/* 读取本地配置文件 */
|
||||
String content = FileUtil.readYml(EasyConstant.CONFIG_PATH);
|
||||
JSONObject object = JSONObject.parseObject(content);
|
||||
|
||||
/* 从配置中心获取配置信息 */
|
||||
JSONObject config = RemoteConfigUtil.remoteConfig(object);
|
||||
|
||||
/* 保证端口号不被修改 */
|
||||
config.put("port",object.get("port"));
|
||||
|
||||
/* 将配置信息缓存下来 */
|
||||
constants.setAttr("config", config);
|
||||
|
||||
/* 加载log4j配置文件 */
|
||||
GogeLog4jUtil.initLog4jConfig(config);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载配置文件出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
* @return json
|
||||
*/
|
||||
public static JSONObject getConfig() {
|
||||
Object obj = constants.getAttr("config");
|
||||
if(obj != null) {
|
||||
JSONObject jsonObject = (JSONObject)obj;
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JDBC配置信息
|
||||
*
|
||||
* @return 配置信息
|
||||
*/
|
||||
public static JSONObject getJdbcConfig() throws Exception {
|
||||
try {
|
||||
JSONObject jsonObject = getConfig();
|
||||
|
||||
if (jsonObject != null) {
|
||||
|
||||
JSONObject jdbc = JSONObject.parseObject(JSON.toJSONString(jsonObject.get("jdbc")));
|
||||
|
||||
return jdbc;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new Exception("从配置文件中读取jdbc模块配置出错",e);
|
||||
}
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 文件帮助
|
||||
*
|
||||
* @author yuye
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
private static GogeLogger logger = GogeLogger.getLogger(FileUtil.class);
|
||||
|
||||
public static String local = null;
|
||||
|
||||
/**
|
||||
* 根据文件路径 获取文件中的字符串内容
|
||||
*
|
||||
* @param path 路径
|
||||
* @return str
|
||||
*/
|
||||
public static String readFileString(String path) {
|
||||
InputStream inputStream = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
inputStream = FileUtil.class.getResourceAsStream(path);
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String str = "";
|
||||
while ((str = reader.readLine()) != null) {
|
||||
sb.append(str);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
if (local == null) {
|
||||
logger.error("", e);
|
||||
} else {
|
||||
logger.warn("自定义mybatis配置文件加载失败或者不存在,将自动使用默认配置");
|
||||
}
|
||||
} finally {
|
||||
try{
|
||||
reader.close();
|
||||
inputStream.close();
|
||||
} catch (Exception e){
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径 获取yml配置文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @return str
|
||||
*/
|
||||
public static String readYml(String path) throws Exception {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = FileUtil.class.getResourceAsStream(path);
|
||||
HashMap testEntity = org.ho.yaml.Yaml.loadType(inputStream, HashMap.class);//如果是读入Map,这里不可以写Map接口,必须写实现
|
||||
return JSON.toJSONString(testEntity);
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
throw e;
|
||||
} finally {
|
||||
try{
|
||||
inputStream.close();
|
||||
} catch (Exception e){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将file转化成二进制流
|
||||
*
|
||||
* @param file 文件流
|
||||
* @return 转化后的二进制流
|
||||
*/
|
||||
public static byte[] getFileToByte(File file) {
|
||||
InputStream is = null;
|
||||
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
|
||||
byte[] by = new byte[(int) file.length()];
|
||||
try {
|
||||
is = new FileInputStream(file);
|
||||
byte[] bb = new byte[2048];
|
||||
int ch;
|
||||
ch = is.read(bb);
|
||||
while (ch != -1) {
|
||||
bytestream.write(bb, 0, ch);
|
||||
ch = is.read(bb);
|
||||
}
|
||||
return bytestream.toByteArray();
|
||||
} catch (Exception ex) {
|
||||
logger.error("File转化成byte[]报错",ex);
|
||||
return null;
|
||||
} finally {
|
||||
try{
|
||||
bytestream.close();
|
||||
is.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将InputStream转化成二进制流
|
||||
* @param inStream InputStream
|
||||
* @return 二进制流
|
||||
*/
|
||||
public static byte[] getInputStreamToByte(InputStream inStream) {
|
||||
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
byte[] buff = new byte[100];
|
||||
int rc = 0;
|
||||
while ((rc = inStream.read(buff, 0, 100)) > 0) {
|
||||
swapStream.write(buff, 0, rc);
|
||||
}
|
||||
return swapStream.toByteArray();
|
||||
} catch (Exception e) {
|
||||
logger.error("InputStream转化成byte[]报错",e);
|
||||
return null;
|
||||
} finally {
|
||||
try{
|
||||
swapStream.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static byte[] getBufferedImageToByte(BufferedImage bufferedImage){
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try{
|
||||
ImageIO.write(bufferedImage, "gif", out);
|
||||
return out.toByteArray();
|
||||
} catch (Exception e){
|
||||
logger.error("BufferedImage转化成byte[]报错",e);
|
||||
return null;
|
||||
} finally {
|
||||
try{
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* HTTP工具类
|
||||
*/
|
||||
public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发起post请求
|
||||
* @param url 链接
|
||||
* @param params 参数
|
||||
* @return 响应结果
|
||||
*/
|
||||
public static Object post(String url, Map<String,String> params) throws Exception {
|
||||
return request(url,params,"POST");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起get请求
|
||||
* @param url 链接
|
||||
* @param params 参数
|
||||
* @return 响应结果
|
||||
*/
|
||||
public static Object get(String url, Map<String,String> params) throws Exception {
|
||||
return request(url,params,"GET");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起请求
|
||||
* @param strUrl 链接
|
||||
* @param params 参数
|
||||
* @param method 请求方式
|
||||
* @return 响应结果
|
||||
*/
|
||||
public static Object request(String strUrl, Map<String,String> params,String method) throws Exception{
|
||||
|
||||
try {
|
||||
URL url = new URL(strUrl);
|
||||
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
||||
httpConn.setRequestMethod(method);
|
||||
if(params != null){
|
||||
for(String key : params.keySet()){
|
||||
httpConn.setRequestProperty(key,params.get(key));
|
||||
}
|
||||
}
|
||||
InputStreamReader input = new InputStreamReader(httpConn.getInputStream(), "UTF-8");
|
||||
BufferedReader bufReader = new BufferedReader(input);
|
||||
String line = "";
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
while ((line = bufReader.readLine()) != null) {
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
return stringBuffer.toString();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
/**
|
||||
* 判断字符串是否与规则匹配
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class MatchUtil {
|
||||
|
||||
/**
|
||||
* 判断带通配符的字符串与另一个字符串是否匹配
|
||||
* @param rule 规则
|
||||
* @param str 字符串
|
||||
* @return boolean
|
||||
*/
|
||||
public static Boolean isMatch(String rule,String str){
|
||||
if(rule==null || str == null){
|
||||
return false;
|
||||
}
|
||||
int ind = rule.indexOf("*");
|
||||
if(ind>-1){
|
||||
if(rule.length()==1){
|
||||
return true;
|
||||
}else{
|
||||
String ru = rule.replaceAll("\\*", "([a-zA-Z1-9]+)");
|
||||
return str.matches(ru);
|
||||
}
|
||||
}else{
|
||||
return rule.equals(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* 错误提示信息 工具类
|
||||
*/
|
||||
public class MesUtil {
|
||||
|
||||
/**
|
||||
* 获取错误提示信息
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject getMes(Integer errorCode,String errorMsg){
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("error_code", errorCode);
|
||||
jsonObject.put("error_info", errorMsg);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* 读取class文件
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ReadClass {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(ReadClass.class);
|
||||
|
||||
|
||||
/**
|
||||
* 获取某包下(包括该包的所有子包)所有类
|
||||
*
|
||||
* @param packageName
|
||||
* 包名
|
||||
* @return 类的完整名称
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static Set<String> loadClassList(String packageName) throws IOException {
|
||||
if(packageName == null) {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
return getClasses(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从包package中获取所有的Class
|
||||
*
|
||||
* @param pack
|
||||
* @return
|
||||
*/
|
||||
private static Set<String> getClasses(String pack) {
|
||||
|
||||
// 第一个class类的集合
|
||||
Set<String> classes = new LinkedHashSet<String>();
|
||||
// 是否循环迭代
|
||||
boolean recursive = true;
|
||||
// 获取包的名字 并进行替换
|
||||
String packageName = pack;
|
||||
String packageDirName = packageName.replace('.', '/');
|
||||
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
||||
Enumeration<URL> dirs;
|
||||
try {
|
||||
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
||||
// 循环迭代下去
|
||||
while (dirs.hasMoreElements()) {
|
||||
// 获取下一个元素
|
||||
URL url = dirs.nextElement();
|
||||
// 得到协议的名称
|
||||
String protocol = url.getProtocol();
|
||||
// 如果是以文件的形式保存在服务器上
|
||||
if ("file".equals(protocol)) {
|
||||
// 获取包的物理路径
|
||||
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
|
||||
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
||||
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
|
||||
} else if ("jar".equals(protocol)) {
|
||||
// 如果是jar包文件
|
||||
// 定义一个JarFile
|
||||
JarFile jar;
|
||||
try {
|
||||
// 获取jar
|
||||
jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
||||
// 从此jar包 得到一个枚举类
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
// 同样的进行循环迭代
|
||||
while (entries.hasMoreElements()) {
|
||||
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
|
||||
JarEntry entry = entries.nextElement();
|
||||
String name = entry.getName();
|
||||
// 如果是以/开头的
|
||||
if (name.charAt(0) == '/') {
|
||||
// 获取后面的字符串
|
||||
name = name.substring(1);
|
||||
}
|
||||
// 如果前半部分和定义的包名相同
|
||||
if (name.startsWith(packageDirName)) {
|
||||
int idx = name.lastIndexOf('/');
|
||||
// 如果以"/"结尾 是一个包
|
||||
if (idx != -1) {
|
||||
// 获取包名 把"/"替换成"."
|
||||
packageName = name.substring(0, idx).replace('/', '.');
|
||||
}
|
||||
// 如果可以迭代下去 并且是一个包
|
||||
if ((idx != -1) || recursive) {
|
||||
// 如果是一个.class文件 而且不是目录
|
||||
if (name.endsWith(".class") && !entry.isDirectory()) {
|
||||
// 去掉后面的".class" 获取真正的类名
|
||||
String className = name.substring(packageName.length() + 1, name.length() - 6);
|
||||
// 添加到classes
|
||||
classes.add(packageName + '.' + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// log.error("在扫描用户定义视图时从jar包获取文件出错");
|
||||
log.error("",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("扫描["+packageName+"]包下的类发送错误",e);
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以文件的形式来获取包下的所有Class
|
||||
*
|
||||
* @param packageName
|
||||
* @param packagePath
|
||||
* @param recursive
|
||||
* @param classes
|
||||
*/
|
||||
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive,
|
||||
Set<String> classes) {
|
||||
// 获取此包的目录 建立一个File
|
||||
File dir = new File(packagePath);
|
||||
// 如果不存在或者 也不是目录就直接返回
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
|
||||
return;
|
||||
}
|
||||
// 如果存在 就获取包下的所有文件 包括目录
|
||||
File[] dirfiles = dir.listFiles(new FileFilter() {
|
||||
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
|
||||
public boolean accept(File file) {
|
||||
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
|
||||
}
|
||||
});
|
||||
// 循环所有文件
|
||||
for (File file : dirfiles) {
|
||||
// 如果是目录 则继续扫描
|
||||
if (file.isDirectory()) {
|
||||
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive,
|
||||
classes);
|
||||
} else {
|
||||
// 如果是java类文件 去掉后面的.class 只留下类名
|
||||
String className = file.getName().substring(0, file.getName().length() - 6);
|
||||
classes.add(packageName + '.' + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RemoteConfigUtil {
|
||||
|
||||
/**
|
||||
* 从远程配置中心读取配置信息
|
||||
* @param object 本地配置
|
||||
* @return 远程配置
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public static JSONObject remoteConfig(JSONObject object) throws Exception {
|
||||
try{
|
||||
Map<String,String> params = new HashMap<>();
|
||||
|
||||
/* 读取并判断用户有无使用远程配置中心,如果没有 则直接返回本地配置文件信息 */
|
||||
JSONObject config = object.getJSONObject("config");
|
||||
if(config == null){
|
||||
return object;
|
||||
}
|
||||
|
||||
/* 解析远程配置 并获取数据 */
|
||||
String furl = config.getString("url");
|
||||
String url = EasyConstant.READ_REMOTE_CONFIG.replace("${0}",furl);
|
||||
|
||||
params.put("name",config.getString("name"));
|
||||
params.put("myIp",config.getString("myIp"));
|
||||
params.put("port",object.getString("port"));
|
||||
|
||||
Object result = HttpUtil.post(url,params);
|
||||
|
||||
JSONObject jsonObject = JSONObject.parseObject(result.toString());
|
||||
return jsonObject;
|
||||
} catch (Exception e){
|
||||
throw new Exception("读取远程配置中心失败",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
/**
|
||||
* 字符串工具类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class StringUtil {
|
||||
|
||||
/**
|
||||
* 将字符串首字母转成小写
|
||||
* @param str 参数
|
||||
* @return string
|
||||
*/
|
||||
public static String getFirstLowerCase(String str) {
|
||||
String str2 = str.substring(1);
|
||||
String str3 = str.substring(0,1);
|
||||
|
||||
return str3.toLowerCase()+str2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否为空
|
||||
* @param obj 参数
|
||||
* @return string
|
||||
*/
|
||||
public static boolean isNull(Object obj) {
|
||||
if(obj == null || obj.toString().trim().equals("")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.yuyenews.core.util;
|
||||
|
||||
/**
|
||||
* 线程工具类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ThreadUtil {
|
||||
|
||||
/**
|
||||
* 获取当前线程的ID
|
||||
* @return id
|
||||
*/
|
||||
public static String getThreadIdToTraction() {
|
||||
return getThreadId("traction");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前线程的ID
|
||||
* @param tag
|
||||
* @return id
|
||||
*/
|
||||
public static String getThreadId(String tag) {
|
||||
return String.valueOf(Thread.currentThread().getId())+tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前线程的ID
|
||||
* @return id
|
||||
*/
|
||||
public static String getThreadId() {
|
||||
return String.valueOf(Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-ioc</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-aop</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.yuyenews.ioc.factory;
|
||||
|
||||
import com.yuyenews.aop.proxy.CglibProxy;
|
||||
import com.yuyenews.core.annotation.EasyAop;
|
||||
import com.yuyenews.core.annotation.EasyAopType;
|
||||
import com.yuyenews.core.annotation.Traction;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.model.EasyBeanModel;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* bean工厂
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class BeanFactory {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(BeanFactory.class);
|
||||
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 创建bean
|
||||
* @param className lei
|
||||
* @return duixiang
|
||||
*/
|
||||
public static Object createBean(Class<?> className) throws Exception {
|
||||
try {
|
||||
|
||||
Object hasStart = constants.getAttr(EasyConstant.HAS_START);
|
||||
if(hasStart != null){
|
||||
throw new Exception("只有Goge才可以调用此方法,不可以手动显式调用");
|
||||
}
|
||||
|
||||
Map<String,Class<?>> list = new HashMap<>();
|
||||
|
||||
/* 判断当前类中有没有方法有 aop注解 */
|
||||
getAopClass(className,list);
|
||||
|
||||
/* 如果有aop注解,则通过动态代理来创建bean */
|
||||
if(list != null && list.size()>0) {
|
||||
CglibProxy cglibProxy = new CglibProxy();
|
||||
return cglibProxy.getProxy(className, list);
|
||||
} else {
|
||||
/* 如果没有aop注解,则直接new一个bean */
|
||||
return className.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new Exception("创建["+className.getName()+"]类型的bean对象出现错误",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取aop类
|
||||
* @param className lei
|
||||
* @param list jihe
|
||||
* @throws Exception cuowu
|
||||
*/
|
||||
private static void getAopClass(Class<?> className,Map<String,Class<?>> list) throws Exception {
|
||||
|
||||
EasyAopType allEasyAop = className.getAnnotation(EasyAopType.class);
|
||||
|
||||
Method[] methods = className.getMethods();
|
||||
for(Method method : methods) {
|
||||
EasyAop easyAop = method.getAnnotation(EasyAop.class);
|
||||
Traction traction = method.getAnnotation(Traction.class);
|
||||
|
||||
/* 校验同一个方法上不能同时存在aop和trac注解 */
|
||||
if(easyAop != null && traction != null) {
|
||||
log.error(className.getName()+"类中的["+method.getName()+"]方法同时存在EasyAop和Traction注解");
|
||||
throw new Exception(className.getName()+"类中的["+method.getName()+"]方法同时存在EasyAop和Traction注解");
|
||||
}
|
||||
|
||||
/* 如果类的AOP注解不为空,那么将注解中的监听类 添加到集合中 */
|
||||
if(allEasyAop != null) {
|
||||
list.put(method.getName(),allEasyAop.className());
|
||||
}
|
||||
|
||||
/* 如果方法上也有AOP注解,那么以方法上的为准 */
|
||||
if(easyAop != null) {
|
||||
list.put(method.getName(),easyAop.className());
|
||||
} else if(traction != null) {
|
||||
Class<?> aopClass = Class.forName("com.yuyenews.easy.traction.TractionAop");
|
||||
list.put(method.getName(),aopClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取bean
|
||||
* @param name mingc
|
||||
* @return duix
|
||||
*/
|
||||
public static Object getBean(String name) throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
Object objs2 = constants.getAttr(EasyConstant.EASYBEAN_OBJECTS);
|
||||
Map<String,EasyBeanModel> easyBeanObjs = new HashMap<>();
|
||||
if(objs2 != null) {
|
||||
easyBeanObjs = (Map<String,EasyBeanModel>)objs2;
|
||||
}
|
||||
|
||||
return easyBeanObjs.get(name).getObj();
|
||||
} catch (Exception e) {
|
||||
throw new Exception("找不到name为["+name+"]的bean",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.yuyenews.ioc.load;
|
||||
|
||||
import com.yuyenews.core.annotation.EasyBean;
|
||||
import com.yuyenews.core.annotation.Resource;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.model.EasyBeanModel;
|
||||
import com.yuyenews.core.util.StringUtil;
|
||||
import com.yuyenews.ioc.factory.BeanFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 加载easyBean
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class LoadEasyBean {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(LoadEasyBean.class);
|
||||
|
||||
/**
|
||||
* 获取全局存储空间
|
||||
*/
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 创建easyBean对象,并完成对象注入
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public static void loadBean() throws Exception{
|
||||
try {
|
||||
/* 获取所有的bean数据 */
|
||||
Object objs = constants.getAttr(EasyConstant.EASYBEANS);
|
||||
List<Map<String,Object>> contorls = null;
|
||||
if(objs != null) {
|
||||
contorls = (List<Map<String,Object>>)objs;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 创建bean对象,并保存起来 */
|
||||
Object objs2 = constants.getAttr(EasyConstant.EASYBEAN_OBJECTS);
|
||||
Map<String,EasyBeanModel> easyBeanObjs = new HashMap<>();
|
||||
if(objs2 != null) {
|
||||
easyBeanObjs = (Map<String,EasyBeanModel>)objs2;
|
||||
}
|
||||
for(Map<String,Object> map : contorls) {
|
||||
|
||||
Class<?> cls = (Class<?>)map.get("className");
|
||||
EasyBean easyBean = (EasyBean)map.get("annotation");
|
||||
|
||||
String beanName = easyBean.value();
|
||||
if(beanName == null || beanName.equals("")) {
|
||||
beanName = StringUtil.getFirstLowerCase(cls.getSimpleName());
|
||||
}
|
||||
if(easyBeanObjs.get(beanName) == null) {
|
||||
EasyBeanModel beanModel = new EasyBeanModel();
|
||||
beanModel.setName(beanName);
|
||||
beanModel.setCls(cls);
|
||||
beanModel.setObj(BeanFactory.createBean(cls));
|
||||
easyBeanObjs.put(beanName, beanModel);
|
||||
} else {
|
||||
throw new Exception("已经存在name为["+beanName+"]的bean了");
|
||||
}
|
||||
}
|
||||
/* 注入对象 */
|
||||
iocBean(easyBeanObjs);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载并注入EasyBean的时候出现错误",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* easyBean注入
|
||||
* @param easyBeanObjs 对象
|
||||
*/
|
||||
private static void iocBean(Map<String,EasyBeanModel> easyBeanObjs) throws Exception{
|
||||
|
||||
try {
|
||||
for(String key : easyBeanObjs.keySet()) {
|
||||
EasyBeanModel easyBeanModel = easyBeanObjs.get(key);
|
||||
Object obj = easyBeanModel.getObj();
|
||||
Class<?> cls = easyBeanModel.getCls();
|
||||
/* 获取对象属性,完成注入 */
|
||||
Field[] fields = cls.getDeclaredFields();
|
||||
for(Field f : fields){
|
||||
Resource resource = f.getAnnotation(Resource.class);
|
||||
if(resource!=null){
|
||||
f.setAccessible(true);
|
||||
|
||||
String filedName = resource.value();
|
||||
if(filedName == null || filedName.equals("")) {
|
||||
filedName = f.getName();
|
||||
}
|
||||
|
||||
EasyBeanModel beanModel = easyBeanObjs.get(filedName);
|
||||
if(beanModel!=null){
|
||||
f.set(obj, beanModel.getObj());
|
||||
log.info(cls.getName()+"的属性"+f.getName()+"注入成功");
|
||||
}else{
|
||||
throw new Exception("不存在name为"+filedName+"的easyBean");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 保险起见,重新插入数据 */
|
||||
easyBeanModel.setCls(cls);
|
||||
easyBeanObjs.put(key, easyBeanModel);
|
||||
}
|
||||
|
||||
constants.setAttr(EasyConstant.EASYBEAN_OBJECTS, easyBeanObjs);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载并注入EasyBean的时候出现错误",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-jdbc</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-jdbc-base</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-aop</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yuyenews.jdbc.base;
|
||||
|
||||
public interface BaseInitJdbc {
|
||||
|
||||
/**
|
||||
* 加载配置
|
||||
*/
|
||||
void init() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yuyenews.jdbc.base;
|
||||
|
||||
/**
|
||||
* JDBC代理
|
||||
*/
|
||||
public abstract class BaseJdbcProxy {
|
||||
|
||||
/**
|
||||
* 获取代理对象
|
||||
* @param clazz bean的class
|
||||
* @return 对象
|
||||
*/
|
||||
public abstract Object getProxy(Class<?> clazz);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.yuyenews.jdbc.load;
|
||||
|
||||
|
||||
import com.yuyenews.core.annotation.EasyDao;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.model.EasyBeanModel;
|
||||
import com.yuyenews.core.util.StringUtil;
|
||||
import com.yuyenews.jdbc.base.BaseJdbcProxy;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class LoadDaos {
|
||||
|
||||
/**
|
||||
* 获取全局存储空间
|
||||
*/
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 创建dao对象
|
||||
*/
|
||||
public static void loadDao(BaseJdbcProxy baseProxy) throws Exception{
|
||||
try {
|
||||
|
||||
Object objs = constants.getAttr(EasyConstant.EASYDAOS);
|
||||
if(objs != null) {
|
||||
List<Map<String,Object>> easyDaos = (List<Map<String,Object>>)objs;
|
||||
|
||||
/* 创建bean对象,并保存起来 */
|
||||
Object objs2 = constants.getAttr(EasyConstant.EASYBEAN_OBJECTS);
|
||||
Map<String,EasyBeanModel> easyBeanObjs = new HashMap<>();
|
||||
if(objs2 != null) {
|
||||
easyBeanObjs = (Map<String,EasyBeanModel>)objs2;
|
||||
}
|
||||
|
||||
for(Map<String,Object> map : easyDaos) {
|
||||
Class<?> cls = (Class) map.get("className");
|
||||
EasyDao easyDao = (EasyDao)map.get("annotation");
|
||||
|
||||
String beanName = easyDao.value();
|
||||
if(beanName == null || beanName.equals("")){
|
||||
beanName = StringUtil.getFirstLowerCase(cls.getSimpleName());
|
||||
}
|
||||
if(easyBeanObjs.get(beanName) == null) {
|
||||
EasyBeanModel beanModel = new EasyBeanModel();
|
||||
beanModel.setName(beanName);
|
||||
beanModel.setCls(cls);
|
||||
beanModel.setObj(baseProxy.getProxy(cls));
|
||||
easyBeanObjs.put(beanName, beanModel);
|
||||
} else {
|
||||
throw new Exception("已经存在name为["+beanName+"]的EasyDao了");
|
||||
}
|
||||
}
|
||||
|
||||
constants.setAttr(EasyConstant.EASYBEAN_OBJECTS,easyBeanObjs);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载EasyDao的时候出现错误",e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-jdbc</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-jpa</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-jdbc-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.yuyenews.easy.jpa.init;
|
||||
|
||||
import com.yuyenews.easy.jpa.proxy.JpaProxy;
|
||||
import com.yuyenews.jdbc.base.BaseInitJdbc;
|
||||
import com.yuyenews.jdbc.load.LoadDaos;
|
||||
|
||||
/**
|
||||
* 初始化jdbc
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class InitJdbc implements BaseInitJdbc {
|
||||
|
||||
/**
|
||||
* 加载配置
|
||||
*/
|
||||
@Override
|
||||
public void init() throws Exception{
|
||||
|
||||
/* 加载jpa配置 */
|
||||
|
||||
/* 创建dao对象 */
|
||||
LoadDaos.loadDao(new JpaProxy());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.yuyenews.easy.jpa.proxy;
|
||||
|
||||
|
||||
import com.yuyenews.core.annotation.DataSource;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.util.ThreadUtil;
|
||||
import com.yuyenews.jdbc.base.BaseJdbcProxy;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 代理类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class JpaProxy extends BaseJdbcProxy implements MethodInterceptor {
|
||||
|
||||
private EasySpace easySpace = EasySpace.getEasySpace();
|
||||
|
||||
|
||||
/**
|
||||
* 获取代理对象
|
||||
* @param clazz bean的class
|
||||
* @return 对象
|
||||
*/
|
||||
@Override
|
||||
public Object getProxy(Class<?> clazz) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
// 设置需要创建子类的类
|
||||
enhancer.setSuperclass(clazz);
|
||||
enhancer.setCallback(this);
|
||||
// 通过字节码技术动态创建子类实例
|
||||
return enhancer.create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绑定代理
|
||||
* @param o
|
||||
* @param method
|
||||
* @param args
|
||||
* @param methodProxy
|
||||
* @return obj
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
|
||||
/* 获取当前线程中的sqlSession */
|
||||
Object obj = easySpace.getAttr(ThreadUtil.getThreadIdToTraction());
|
||||
|
||||
|
||||
/* 返回数据 */
|
||||
Object result = null;
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源名称
|
||||
* @param method
|
||||
* @return str
|
||||
*/
|
||||
private String getDataSourceName(Method method) {
|
||||
String dataSourceName = null;
|
||||
DataSource dataSource = method.getAnnotation(DataSource.class);
|
||||
if(dataSource != null) {
|
||||
/* 如果dao的方法上有DataSource注解,则使用注解中的数据源名称 */
|
||||
dataSourceName = dataSource.value();
|
||||
} else {
|
||||
/* 否则使用默认数据源名称 */
|
||||
dataSourceName = easySpace.getAttr("defaultDataSource").toString();
|
||||
}
|
||||
return dataSourceName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-jdbc</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-mybatis</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-jdbc-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.yuyenews.easy.init;
|
||||
|
||||
import com.yuyenews.easy.proxy.MappersProxy;
|
||||
import com.yuyenews.jdbc.base.BaseInitJdbc;
|
||||
import com.yuyenews.jdbc.load.LoadDaos;
|
||||
|
||||
/**
|
||||
* 初始化jdbc
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class InitJdbc implements BaseInitJdbc {
|
||||
|
||||
/**
|
||||
* 加载配置
|
||||
*/
|
||||
@Override
|
||||
public void init() throws Exception{
|
||||
|
||||
/* 加载mybatis配置 */
|
||||
LoadSqlSessionFactory.getLoadSqlSessionFactory();
|
||||
|
||||
/* 创建dao对象 */
|
||||
LoadDaos.loadDao(new MappersProxy());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.yuyenews.easy.init;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
import com.yuyenews.core.util.FileUtil;
|
||||
import com.yuyenews.easy.util.ReadXml;
|
||||
import com.yuyenews.easy.util.extend.MyDataSourceFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.server.ExportException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 组装myBatis配置文件
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class LoadMybatisConfig {
|
||||
|
||||
private static GogeLogger logger = GogeLogger.getLogger(LoadMybatisConfig.class);
|
||||
|
||||
private static EasySpace easySpace = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 获取配置文件并以字符串形式返回
|
||||
* @return str
|
||||
*/
|
||||
public static String getConfigStr() throws Exception {
|
||||
try {
|
||||
FileUtil.local = String.valueOf(ConfigUtil.getJdbcConfig().get("config-location"));
|
||||
String str = FileUtil.readFileString("/"+FileUtil.local);
|
||||
if(str == null) {
|
||||
str = defaultConfig();
|
||||
}
|
||||
|
||||
/* 禁止在mybatis配置文件里配置数据源 */
|
||||
if(str.indexOf("environment") > -1 || str.indexOf("dataSource") > -1 || str.indexOf("environments") > -1) {
|
||||
throw new Exception("不可以在mybatis配置文件里配置数据源");
|
||||
}
|
||||
|
||||
/* 禁止在mybatis配置文件里配置mappers */
|
||||
if(str.indexOf("mappers") > -1 || str.indexOf("mapper") > -1) {
|
||||
throw new Exception("不可以在mybatis配置文件里配置mappers");
|
||||
}
|
||||
|
||||
str = str.replaceAll("</configuration>", "");
|
||||
str += getDataSources();
|
||||
str += getMappers();
|
||||
str += "</configuration>";
|
||||
|
||||
return str;
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载mybatis配置出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有mapper文件路径,并组装成xml格式的字符串返回
|
||||
* @return str
|
||||
*/
|
||||
private static String getMappers() throws Exception {
|
||||
try {
|
||||
String mappers = ConfigUtil.getJdbcConfig().getString("mappers");
|
||||
|
||||
Set<String> xmls = ReadXml.loadXmlList(mappers);
|
||||
|
||||
StringBuffer buffer = new StringBuffer("<mappers>");
|
||||
for(String str : xmls) {
|
||||
buffer.append("<mapper resource=\""+str+"\"/>");
|
||||
}
|
||||
buffer.append("</mappers>");
|
||||
return buffer.toString();
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载mybatis配置文件出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载数据源配置
|
||||
* @return str
|
||||
*/
|
||||
private static String getDataSources() throws Exception {
|
||||
try {
|
||||
String def = "";
|
||||
|
||||
JSONArray array = ConfigUtil.getJdbcConfig().getJSONArray("dataSource");
|
||||
|
||||
StringBuffer dataSource = new StringBuffer("<environments default=\"${def}\">") ;
|
||||
|
||||
List<String> daNames = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
|
||||
JSONObject jsonObject = array.getJSONObject(i);
|
||||
|
||||
ckDsConfig(jsonObject);
|
||||
|
||||
if(i == 0) {
|
||||
def = jsonObject.getString("name");
|
||||
}
|
||||
|
||||
String type = getDataSourceType();
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("<environment id=\""+jsonObject.getString("name")+"\">");
|
||||
buffer.append("<transactionManager type=\"JDBC\"/>");
|
||||
buffer.append("<dataSource type=\""+type+"\">");
|
||||
for(String key : jsonObject.keySet()) {
|
||||
if(!key.equals("name") && !key.equals("type")) {
|
||||
buffer.append("<property name=\""+key+"\" value=\""+jsonObject.get(key)+"\"/>");
|
||||
}
|
||||
}
|
||||
buffer.append("</dataSource>");
|
||||
buffer.append("</environment>");
|
||||
dataSource.append(buffer);
|
||||
|
||||
daNames.add(jsonObject.getString("name"));
|
||||
}
|
||||
|
||||
easySpace.setAttr("dataSourceNames", daNames);
|
||||
easySpace.setAttr("defaultDataSource", def);
|
||||
|
||||
dataSource.append("</environments>");
|
||||
|
||||
return dataSource.toString().replace("${def}", def);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载mybatis数据源出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源类型
|
||||
* @return str
|
||||
*/
|
||||
private static String getDataSourceType() {
|
||||
return MyDataSourceFactory.class.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据源配置
|
||||
* @return str
|
||||
*/
|
||||
private static boolean ckDsConfig(JSONObject jsonObject) throws Exception {
|
||||
if(jsonObject.get("name") == null) {
|
||||
logger.error("数据源没有指定name");
|
||||
throw new Exception("数据源没有指定name");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
* @return str
|
||||
*/
|
||||
private static String defaultConfig() throws Exception {
|
||||
try {
|
||||
|
||||
Object dialect = ConfigUtil.getJdbcConfig().get("dialect");
|
||||
|
||||
if(dialect == null) {
|
||||
/* 方言 默认mysql */
|
||||
dialect = "mysql";
|
||||
}
|
||||
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
stringBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
stringBuffer.append("<!DOCTYPE configuration PUBLIC \"-//mybatis.org//DTD Config 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-config.dtd\">");
|
||||
stringBuffer.append("<configuration>");
|
||||
stringBuffer.append("<properties>");
|
||||
stringBuffer.append("<property name=\"dialect\" value=\""+dialect+"\" />");
|
||||
stringBuffer.append("</properties>");
|
||||
stringBuffer.append("<plugins>");
|
||||
stringBuffer.append("<plugin interceptor=\"com.github.pagehelper.PageHelper\">");
|
||||
stringBuffer.append("<property name=\"dialect\" value=\""+dialect+"\" />");
|
||||
stringBuffer.append("</plugin>");
|
||||
stringBuffer.append("</plugins>");
|
||||
stringBuffer.append("</configuration>");
|
||||
|
||||
return stringBuffer.toString();
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载mybatis配置文件出错",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
package com.yuyenews.easy.init;
|
||||
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 加载
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class LoadSqlSessionFactory {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(LoadSqlSessionFactory.class);
|
||||
|
||||
private static LoadSqlSessionFactory factory;
|
||||
|
||||
private String resource;
|
||||
|
||||
private static EasySpace easySpace = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 单例,防止重复加载配置文件
|
||||
*/
|
||||
private LoadSqlSessionFactory() {}
|
||||
|
||||
/**
|
||||
* 获取本类的对象
|
||||
* @return obj
|
||||
*/
|
||||
public static LoadSqlSessionFactory getLoadSqlSessionFactory() {
|
||||
|
||||
if(factory == null) {
|
||||
factory = new LoadSqlSessionFactory();
|
||||
factory.loadConfig();
|
||||
factory.loadSqlSessionFactorys();
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将配置文件字符串转换成输入流
|
||||
*/
|
||||
private void loadConfig() {
|
||||
try {
|
||||
resource = LoadMybatisConfig.getConfigStr();
|
||||
} catch (Exception e) {
|
||||
logger.error("加载配置文件出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载sqlSessionFactory
|
||||
*/
|
||||
private void loadSqlSessionFactorys() {
|
||||
List<String> daNames = (List<String>) easySpace.getAttr("dataSourceNames");
|
||||
|
||||
Map<String,SqlSessionFactory> maps = new HashMap<>();
|
||||
for(String str : daNames) {
|
||||
InputStream inputStream = new ByteArrayInputStream(resource.getBytes());
|
||||
maps.put(str, new SqlSessionFactoryBuilder().build(inputStream,str));
|
||||
}
|
||||
easySpace.setAttr("sqlSessionFactorys", maps);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sqlSession
|
||||
* @return session
|
||||
*/
|
||||
public SqlSession getSqlSession() {
|
||||
return getSqlSession(null,true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sqlSession
|
||||
* @return session
|
||||
*/
|
||||
public SqlSession getSqlSession(String dataSourceName,Boolean autoCommit) {
|
||||
Map<String,SqlSessionFactory> maps = (Map<String,SqlSessionFactory>) easySpace.getAttr("sqlSessionFactorys");
|
||||
if(dataSourceName == null) {
|
||||
Object defDa = easySpace.getAttr("defaultDataSource");
|
||||
return maps.get(defDa.toString()).openSession(autoCommit);
|
||||
}
|
||||
return maps.get(dataSourceName).openSession(autoCommit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.yuyenews.easy.proxy;
|
||||
|
||||
import com.yuyenews.core.annotation.DataSource;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.util.ThreadUtil;
|
||||
import com.yuyenews.easy.init.LoadSqlSessionFactory;
|
||||
import com.yuyenews.jdbc.base.BaseJdbcProxy;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
import org.apache.ibatis.mapping.SqlCommandType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 代理类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class MappersProxy extends BaseJdbcProxy implements MethodInterceptor {
|
||||
|
||||
private EasySpace easySpace = EasySpace.getEasySpace();
|
||||
|
||||
private LoadSqlSessionFactory loadSqlSessionFactory = LoadSqlSessionFactory.getLoadSqlSessionFactory();
|
||||
|
||||
/**
|
||||
* 获取代理对象
|
||||
* @param clazz bean的class
|
||||
* @return 对象
|
||||
*/
|
||||
@Override
|
||||
public Object getProxy(Class<?> clazz) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
// 设置需要创建子类的类
|
||||
enhancer.setSuperclass(clazz);
|
||||
enhancer.setCallback(this);
|
||||
// 通过字节码技术动态创建子类实例
|
||||
return enhancer.create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绑定代理
|
||||
* @param o
|
||||
* @param method
|
||||
* @param args
|
||||
* @param methodProxy
|
||||
* @return obj
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
|
||||
/* 获取当前线程中的sqlSession */
|
||||
Object obj = easySpace.getAttr(ThreadUtil.getThreadIdToTraction());
|
||||
|
||||
/* 用来执行sql的sqlSession */
|
||||
SqlSession session = null;
|
||||
|
||||
/* 是否需要手动关闭sqlSession(默认不需要) */
|
||||
Boolean flag = false;
|
||||
|
||||
/* 返回数据 */
|
||||
Object result = null;
|
||||
|
||||
/* 获取数据源名称 */
|
||||
String dataSourceName = getDataSourceName(method);
|
||||
|
||||
if(obj != null) {
|
||||
/* 如果当前线程中有sqlSession 则从当前线程中获取sqlSession */
|
||||
Map<String,SqlSession> sqlSessions = (Map<String,SqlSession>)obj;
|
||||
session = sqlSessions.get(dataSourceName);
|
||||
} else {
|
||||
/* 否则 手动获取(这种情况,当执行完以后需要手动关闭sqlSession) */
|
||||
session = loadSqlSessionFactory.getSqlSession(dataSourceName, false);
|
||||
flag = true;
|
||||
}
|
||||
|
||||
/* 获取要执行的sql的ID */
|
||||
String statement = method.getName();
|
||||
|
||||
/* 根据要执行的sql的ID 获取这条sql的类型是select还是update */
|
||||
SqlCommandType tag = session.getConfiguration().getMappedStatement(statement).getSqlCommandType();
|
||||
String commType = tag.toString().toUpperCase();
|
||||
|
||||
if(commType.equals("SELECT")) {
|
||||
/* 如果是select,则判断方法的返回值是不是list */
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if(returnType.getName().equals(List.class.getName())) {
|
||||
/* 如果方法的返回值是list,则执行selectList方法 */
|
||||
if(args != null && args.length > 0 && args[0] != null) {
|
||||
result = session.selectList(statement, args[0]);
|
||||
} else {
|
||||
result = session.selectList(statement);
|
||||
}
|
||||
} else {
|
||||
/* 如果不是list,则执行selectOne方法 */
|
||||
if(args != null && args.length > 0 && args[0] != null) {
|
||||
result = session.selectOne(statement, args[0]);
|
||||
} else {
|
||||
result = session.selectOne(statement);
|
||||
}
|
||||
}
|
||||
|
||||
} else if(commType.equals("UPDATE") || commType.equals("INSERT") || commType.equals("DELETE")) {
|
||||
/* 如果要执行的sql是update类型(增删改),则执行update方法 */
|
||||
if(args != null && args.length > 0 && args[0] != null) {
|
||||
result = session.update(statement, args[0]);
|
||||
} else {
|
||||
result = session.update(statement);
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
/* 如果sqlSession是手动获取的,那么执行完以后要立刻提交事务 */
|
||||
session.commit();
|
||||
}
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
/* 手工关闭sqlSession 节约回收的开销 */
|
||||
session.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源名称
|
||||
* @param method
|
||||
* @return str
|
||||
*/
|
||||
private String getDataSourceName(Method method) {
|
||||
String dataSourceName = null;
|
||||
DataSource dataSource = method.getAnnotation(DataSource.class);
|
||||
if(dataSource != null) {
|
||||
/* 如果dao的方法上有DataSource注解,则使用注解中的数据源名称 */
|
||||
dataSourceName = dataSource.value();
|
||||
} else {
|
||||
/* 否则使用默认数据源名称 */
|
||||
dataSourceName = easySpace.getAttr("defaultDataSource").toString();
|
||||
}
|
||||
return dataSourceName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.yuyenews.easy.traction;
|
||||
|
||||
import com.yuyenews.aop.base.BaseAop;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.ThreadUtil;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 事务管理aop
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class TractionAop implements BaseAop {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(TractionAop.class);
|
||||
|
||||
private static EasySpace easySpace = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 获取数据库连接,并设置为不自动提交
|
||||
*
|
||||
* 将获取到的连接 放到缓存中
|
||||
*
|
||||
* @param args canshu
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void startMethod(Object[] args) {
|
||||
try {
|
||||
Map<String,SqlSessionFactory> maps = (Map<String,SqlSessionFactory>)easySpace.getAttr("sqlSessionFactorys");
|
||||
|
||||
Map<String,SqlSession> sqlSessions = new HashMap<>();
|
||||
|
||||
for(String key : maps.keySet()) {
|
||||
sqlSessions.put(key, maps.get(key).openSession(false));
|
||||
}
|
||||
|
||||
easySpace.setAttr(ThreadUtil.getThreadIdToTraction(), sqlSessions);
|
||||
} catch (Exception e) {
|
||||
logger.error("开启事务出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获取当前线程的数据库连接,并提交事务
|
||||
*
|
||||
* @param args canshu
|
||||
*/
|
||||
public void endMethod(Object[] args) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,SqlSession> sqlSessions = (Map<String,SqlSession>)easySpace.getAttr(ThreadUtil.getThreadIdToTraction());
|
||||
|
||||
for(String key : sqlSessions.keySet()) {
|
||||
SqlSession session = sqlSessions.get(key);
|
||||
session.commit();
|
||||
session.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("提交事务出错",e);
|
||||
} finally {
|
||||
easySpace.remove(ThreadUtil.getThreadIdToTraction());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获取当前线程的数据库连接,并回滚事务
|
||||
* @param e 异常
|
||||
*/
|
||||
public void exp(Throwable e) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,SqlSession> sqlSessions = (Map<String,SqlSession>)easySpace.getAttr(ThreadUtil.getThreadIdToTraction());
|
||||
|
||||
for(String key : sqlSessions.keySet()) {
|
||||
SqlSession session = sqlSessions.get(key);
|
||||
session.rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
logger.error("",e);
|
||||
} catch (Exception ex) {
|
||||
logger.error("回滚事务出错",ex);
|
||||
} finally {
|
||||
easySpace.remove(ThreadUtil.getThreadIdToTraction());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.yuyenews.easy.util;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* 读取class文件
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ReadXml {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(ReadXml.class);
|
||||
|
||||
|
||||
/**
|
||||
* 获取某包下(包括该包的所有子包)所有xml
|
||||
*
|
||||
* @param packageName
|
||||
* 包名
|
||||
* @return xml的完整名称
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
public static Set<String> loadXmlList(String packageName) throws IOException {
|
||||
if(packageName == null) {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
return getXmls(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从包package中获取所有的xml
|
||||
*
|
||||
* @param pack
|
||||
* @return set
|
||||
*/
|
||||
private static Set<String> getXmls(String pack) {
|
||||
|
||||
// 第一个class类的集合
|
||||
Set<String> classes = new LinkedHashSet<String>();
|
||||
// 是否循环迭代
|
||||
boolean recursive = true;
|
||||
// 获取包的名字 并进行替换
|
||||
String packageName = pack;
|
||||
String packageDirName = packageName.replace('.', '/');
|
||||
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
||||
Enumeration<URL> dirs;
|
||||
try {
|
||||
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
||||
// 循环迭代下去
|
||||
while (dirs.hasMoreElements()) {
|
||||
// 获取下一个元素
|
||||
URL url = dirs.nextElement();
|
||||
// 得到协议的名称
|
||||
String protocol = url.getProtocol();
|
||||
// 如果是以文件的形式保存在服务器上
|
||||
if ("file".equals(protocol)) {
|
||||
// 获取包的物理路径
|
||||
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
|
||||
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
||||
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
|
||||
} else if ("jar".equals(protocol)) {
|
||||
// 如果是jar包文件
|
||||
// 定义一个JarFile
|
||||
JarFile jar;
|
||||
try {
|
||||
// 获取jar
|
||||
jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
||||
// 从此jar包 得到一个枚举类
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
// 同样的进行循环迭代
|
||||
while (entries.hasMoreElements()) {
|
||||
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
|
||||
JarEntry entry = entries.nextElement();
|
||||
String name = entry.getName();
|
||||
// 如果是以/开头的
|
||||
if (name.charAt(0) == '/') {
|
||||
// 获取后面的字符串
|
||||
name = name.substring(1);
|
||||
}
|
||||
// 如果前半部分和定义的包名相同
|
||||
if (name.startsWith(packageDirName)) {
|
||||
int idx = name.lastIndexOf('/');
|
||||
// 如果以"/"结尾 是一个包
|
||||
if (idx != -1) {
|
||||
// 获取包名 把"/"替换成"."
|
||||
packageName = name.substring(0, idx);
|
||||
}
|
||||
// 如果可以迭代下去 并且是一个包
|
||||
if ((idx != -1) || recursive) {
|
||||
// 如果是一个.xml文件 而且不是目录
|
||||
if (name.endsWith(".xml") && !entry.isDirectory()) {
|
||||
// 去掉后面的".class" 获取真正的类名
|
||||
String className = name.substring(packageName.length() + 1);
|
||||
// 添加到classes
|
||||
classes.add(packageName + '/' + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// log.error("在扫描用户定义视图时从jar包获取文件出错");
|
||||
log.error("",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("扫描["+packageName+"]包下的类发送错误",e);
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以文件的形式来获取包下的所有Class
|
||||
*
|
||||
* @param packageName
|
||||
* @param packagePath
|
||||
* @param recursive
|
||||
* @param classes
|
||||
*/
|
||||
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive,
|
||||
Set<String> classes) {
|
||||
// 获取此包的目录 建立一个File
|
||||
File dir = new File(packagePath);
|
||||
// 如果不存在或者 也不是目录就直接返回
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
|
||||
return;
|
||||
}
|
||||
// 如果存在 就获取包下的所有文件 包括目录
|
||||
File[] dirfiles = dir.listFiles(new FileFilter() {
|
||||
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.xml结尾的文件
|
||||
public boolean accept(File file) {
|
||||
return (recursive && file.isDirectory()) || (file.getName().endsWith(".xml"));
|
||||
}
|
||||
});
|
||||
// 循环所有文件
|
||||
for (File file : dirfiles) {
|
||||
// 如果是目录 则继续扫描
|
||||
if (file.isDirectory()) {
|
||||
findAndAddClassesInPackageByFile(packageName + "/" + file.getName(), file.getAbsolutePath(), recursive,
|
||||
classes);
|
||||
} else {
|
||||
String className = file.getName();
|
||||
classes.add(packageName + '/' + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.yuyenews.easy.util.extend;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSourceFactory;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import org.apache.ibatis.datasource.DataSourceFactory;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MyDataSourceFactory extends DruidDataSourceFactory implements DataSourceFactory {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(MyDataSourceFactory.class);
|
||||
|
||||
protected Properties properties;
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties props) {
|
||||
this.properties = props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSource getDataSource() {
|
||||
try {
|
||||
return createDataSource(properties);
|
||||
} catch (Exception e) {
|
||||
logger.error("",e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<artifactId>mars-jdbc</artifactId>
|
||||
|
||||
<modules>
|
||||
<module>mars-mybatis</module>
|
||||
<module>mars-jpa</module>
|
||||
<module>mars-jdbc-base</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-mvc</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-netty</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.yuyenews.base;
|
||||
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
|
||||
/**
|
||||
* 拦截器基类,强制继承
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public interface BaseInterceptor {
|
||||
|
||||
/**
|
||||
* 通过
|
||||
*/
|
||||
String SUCCESS = "success";
|
||||
|
||||
/**
|
||||
* 不通过
|
||||
*/
|
||||
String ERROR = "error";
|
||||
|
||||
/**
|
||||
* 控制层执行之前
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
Object startRequest(HttpRequest request,HttpResponse response);
|
||||
|
||||
/**
|
||||
* 控制层执行之后
|
||||
* @param request
|
||||
* @param response
|
||||
* @param obj 控制层返回的数据
|
||||
* @return
|
||||
*/
|
||||
Object endRequest(HttpRequest request,HttpResponse response,Object obj);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.yuyenews.logs;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* controller方法打印日志
|
||||
*/
|
||||
public class LogAop {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(LogAop.class);
|
||||
|
||||
private Class cls;
|
||||
private String methodName;
|
||||
|
||||
public LogAop(Class cls,String methodName){
|
||||
this.cls = cls;
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* controller方法开始执行
|
||||
* @param args
|
||||
*/
|
||||
public void startMethod(Object[] args) {
|
||||
Object obj = args[0];
|
||||
if(obj != null && obj instanceof HttpRequest){
|
||||
HttpRequest request = (HttpRequest)obj;
|
||||
Map<String, Object> params = request.getParemeters();
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("开始执行");
|
||||
buffer.append(cls.getName());
|
||||
buffer.append("->");
|
||||
buffer.append(methodName);
|
||||
buffer.append(",参数:[");
|
||||
buffer.append(JSONObject.toJSONString(params));
|
||||
buffer.append("]");
|
||||
|
||||
logger.info(buffer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* controller方法结束执行
|
||||
* @param args
|
||||
* @param result
|
||||
*/
|
||||
public void endMethod(Object[] args,Object result) {
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("执行结束");
|
||||
buffer.append(cls.getName());
|
||||
buffer.append("->");
|
||||
buffer.append(methodName);
|
||||
buffer.append(",返回数据:[");
|
||||
buffer.append(JSONObject.toJSONString(result));
|
||||
buffer.append("]");
|
||||
|
||||
logger.info(buffer.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* controller方法出异常
|
||||
* @param e
|
||||
*/
|
||||
public void exp(Throwable e){
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("执行异常");
|
||||
buffer.append(cls.getName());
|
||||
buffer.append("->");
|
||||
buffer.append(methodName);
|
||||
buffer.append(",异常信息:");
|
||||
|
||||
logger.error(buffer.toString(),e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.yuyenews.proxy;
|
||||
|
||||
import com.yuyenews.core.annotation.EasyLog;
|
||||
import com.yuyenews.logs.LogAop;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 代理类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class MvcCglibProxy implements MethodInterceptor {
|
||||
|
||||
private Enhancer enhancer;
|
||||
|
||||
private Class cls;
|
||||
|
||||
/**
|
||||
* 获取代理对象
|
||||
* @param clazz bean的class
|
||||
* @return 对象
|
||||
*/
|
||||
public Object getProxy(Class<?> clazz) {
|
||||
this.cls = clazz;
|
||||
|
||||
enhancer = new Enhancer();
|
||||
// 设置需要创建子类的类
|
||||
enhancer.setSuperclass(clazz);
|
||||
enhancer.setCallback(this);
|
||||
// 通过字节码技术动态创建子类实例
|
||||
return enhancer.create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绑定代理
|
||||
*/
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
LogAop c = null;
|
||||
|
||||
EasyLog easyLog = method.getAnnotation(EasyLog.class);
|
||||
if(easyLog != null){
|
||||
c = new LogAop(cls,method.getName());
|
||||
c.startMethod(args);
|
||||
}
|
||||
|
||||
try{
|
||||
Object o1 = methodProxy.invokeSuper(o, args);
|
||||
|
||||
if(c != null){
|
||||
c.endMethod(args,o1);
|
||||
}
|
||||
|
||||
return o1;
|
||||
} catch (Throwable e) {
|
||||
if(c != null) {
|
||||
c.exp(e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.yuyenews.remote.config;
|
||||
|
||||
import com.yuyenews.core.annotation.Controller;
|
||||
import com.yuyenews.core.annotation.EasyLog;
|
||||
import com.yuyenews.core.annotation.EasyMapping;
|
||||
import com.yuyenews.core.annotation.enums.RequestMetohd;
|
||||
import com.yuyenews.core.remote.config.RemoteConfigService;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 修改远程配置后 接受配置中心的通知
|
||||
*/
|
||||
@Controller
|
||||
public class RemoteConfigController {
|
||||
|
||||
/**
|
||||
* 重新加载配置
|
||||
* @param request
|
||||
* @param response
|
||||
* @return 结果
|
||||
*/
|
||||
@EasyMapping(value = "reloadConfig",method = RequestMetohd.POST)
|
||||
@EasyLog
|
||||
public Map<String,Object> reloadConfig(HttpRequest request, HttpResponse response) {
|
||||
Object config = request.getParemeter("config");
|
||||
String result = RemoteConfigService.reloadConfig(config);
|
||||
|
||||
Map<String,Object> returns = new HashMap<>();
|
||||
if(result.equals("ok")){
|
||||
returns.put("msg","通知成功");
|
||||
returns.put("success","ok");
|
||||
} else {
|
||||
returns.put("msg","通知失败");
|
||||
returns.put("success","no");
|
||||
}
|
||||
return returns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.yuyenews.resolve;
|
||||
|
||||
import com.yuyenews.base.BaseInterceptor;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
import com.yuyenews.easy.util.RequestUtil;
|
||||
import com.yuyenews.resolve.model.EasyMappingModel;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行器
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ExecuteEasy {
|
||||
|
||||
private GogeLogger log = GogeLogger.getLogger(ExecuteEasy.class);
|
||||
|
||||
private static ExecuteEasy executeEasy;
|
||||
|
||||
private ExecuteEasy() {
|
||||
}
|
||||
|
||||
public static ExecuteEasy getExecuteEasy() {
|
||||
if (executeEasy == null) {
|
||||
executeEasy = new ExecuteEasy();
|
||||
}
|
||||
return executeEasy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行controller
|
||||
* @param easyMappingModel duix
|
||||
* @param method fangfa
|
||||
* @param request qingqiu
|
||||
* @param response xiangying
|
||||
* @return duix
|
||||
*/
|
||||
public Object execute(EasyMappingModel easyMappingModel, HttpMethod method, HttpRequest request, HttpResponse response) {
|
||||
|
||||
try {
|
||||
|
||||
if(easyMappingModel == null) {
|
||||
return MesUtil.getMes(404,"服务器上没有相应的接口");
|
||||
}
|
||||
|
||||
String strMethod = method.name().toString().toLowerCase();
|
||||
|
||||
String mathodReuest = easyMappingModel.getRequestMetohd().name().toLowerCase();
|
||||
|
||||
if (strMethod.equals(mathodReuest)) {
|
||||
|
||||
/* 获取拦截器 并执行 控制层执行前的方法 */
|
||||
String uriEnd = RequestUtil.getUriName(request);
|
||||
List<Object> list = ExecuteInters.getInters(uriEnd);
|
||||
Object inres = ExecuteInters.executeIntersStart(list,request, response);
|
||||
if(!inres.toString().equals(BaseInterceptor.SUCCESS)) {
|
||||
return inres;
|
||||
}
|
||||
|
||||
/* 获取要执行的controller的信息 */
|
||||
Object obj = easyMappingModel.getObject();
|
||||
Class<?> cls = easyMappingModel.getCls();
|
||||
Method method2 = cls.getDeclaredMethod(easyMappingModel.getMethod(), new Class[] { HttpRequest.class, HttpResponse.class });
|
||||
|
||||
/* 获取controller返回值的类型 */
|
||||
Class cl = method2.getReturnType();
|
||||
String st = cl.getName();
|
||||
|
||||
Object result = null;
|
||||
if(st.toLowerCase().trim().equals("void")){
|
||||
method2.invoke(obj, new Object[] { request, response });
|
||||
result = "void405cb55d6781877e9e930aa8e046098b";
|
||||
} else {
|
||||
result = method2.invoke(obj, new Object[] { request, response });
|
||||
}
|
||||
|
||||
/* 执行拦截器 在控制层执行后的方法 */
|
||||
Object inres2 = ExecuteInters.executeIntersEnd(list,request, response,result);
|
||||
if(!inres2.toString().equals(BaseInterceptor.SUCCESS)) {
|
||||
return inres2;
|
||||
}
|
||||
|
||||
return result;
|
||||
} else {
|
||||
/* 如果请求方式和controller的映射不一致,则提示客户端 */
|
||||
return MesUtil.getMes(403,"此接口的请求方式为[" + mathodReuest + "]");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("执行控制层的时候报错",e);
|
||||
return MesUtil.getMes(500,"执行控制层的时候报错");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.yuyenews.resolve;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.base.BaseInterceptor;
|
||||
import com.yuyenews.core.annotation.EasyInterceptor;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MatchUtil;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 执行拦截器
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ExecuteInters {
|
||||
|
||||
private static GogeLogger logger = GogeLogger.getLogger(ExecuteInters.class);
|
||||
|
||||
/**
|
||||
* 执行拦截器的开始方法
|
||||
* @param list jihe
|
||||
* @param request qingqiu
|
||||
* @param response xiangying
|
||||
* @return duix
|
||||
*/
|
||||
public static Object executeIntersStart(List<Object> list,HttpRequest request, HttpResponse response) {
|
||||
Class<?> clss = null;
|
||||
try {
|
||||
for(Object obj : list) {
|
||||
clss = obj.getClass();
|
||||
|
||||
Method method2 = clss.getDeclaredMethod("startRequest", new Class[] { HttpRequest.class, HttpResponse.class });
|
||||
Object result = method2.invoke(obj, new Object[] { request, response });
|
||||
if(!result.toString().equals(BaseInterceptor.SUCCESS)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseInterceptor.SUCCESS;
|
||||
} catch (Exception e) {
|
||||
logger.error("执行拦截器报错,拦截器类型["+clss.getName()+"]",e);
|
||||
return errorResult(clss);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行拦截器的结束方法
|
||||
* @param list jihe
|
||||
* @param request qingqiu
|
||||
* @param response xiangying
|
||||
* @return duix
|
||||
*/
|
||||
public static Object executeIntersEnd(List<Object> list,HttpRequest request, HttpResponse response,Object objs) {
|
||||
Class<?> clss = null;
|
||||
try {
|
||||
|
||||
for(Object obj : list) {
|
||||
clss = obj.getClass();
|
||||
|
||||
Method method2 = clss.getDeclaredMethod("endRequest", new Class[] { HttpRequest.class, HttpResponse.class, Object.class });
|
||||
Object result = method2.invoke(obj, new Object[] { request, response, objs });
|
||||
if(!result.toString().equals(BaseInterceptor.SUCCESS)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseInterceptor.SUCCESS;
|
||||
} catch (Exception e) {
|
||||
logger.error("执行拦截器报错,拦截器类型["+clss.getName()+"]",e);
|
||||
return errorResult(clss);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有符合条件的拦截器
|
||||
* @param uriEnd uel
|
||||
* @return duix
|
||||
*/
|
||||
public static List<Object> getInters(String uriEnd){
|
||||
|
||||
try {
|
||||
List<Object> list = new ArrayList<>();
|
||||
|
||||
Object objs = EasySpace.getEasySpace().getAttr(EasyConstant.INTERCEPTORS);
|
||||
|
||||
if(objs != null) {
|
||||
List<Map<String,Object>> interceptors = (List<Map<String,Object>>)objs;
|
||||
|
||||
for(Map<String,Object> map : interceptors) {
|
||||
|
||||
EasyInterceptor easyInterceptor = (EasyInterceptor)map.get("annotation");
|
||||
String pattern = easyInterceptor.pattern();
|
||||
|
||||
if(MatchUtil.isMatch(pattern, uriEnd)){
|
||||
Class cls = (Class)map.get("className");
|
||||
list.add(cls.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
} catch (Exception e) {
|
||||
logger.error("读取拦截器报错",e);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误信息
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
private static JSONObject errorResult(Class<?> cls) {
|
||||
return MesUtil.getMes(500,"执行拦截器报错,拦截器类型["+cls.getName()+"]");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.yuyenews.resolve;
|
||||
|
||||
import com.yuyenews.core.annotation.Controller;
|
||||
import com.yuyenews.core.annotation.EasyMapping;
|
||||
import com.yuyenews.core.annotation.Resource;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.model.EasyBeanModel;
|
||||
import com.yuyenews.proxy.MvcCglibProxy;
|
||||
import com.yuyenews.resolve.model.EasyMappingModel;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 加载所有的controller,并完成注入
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class LoadController {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(LoadController.class);
|
||||
|
||||
/**
|
||||
* 获取全局存储空间
|
||||
*/
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 创建controller对象,并将服务层对象注入进去
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void loadContrl() throws Exception{
|
||||
|
||||
try {
|
||||
Map<String,EasyMappingModel> controlObjects = new HashMap<>();
|
||||
|
||||
/* 获取所有的controller数据 */
|
||||
Object objs = constants.getAttr(EasyConstant.CONTROLLERS);
|
||||
List<Map<String,Object>> contorls = null;
|
||||
if(objs != null) {
|
||||
contorls = (List<Map<String,Object>>)objs;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String,EasyBeanModel> easyBeanObjs = getEasyBeans();
|
||||
|
||||
for(Map<String,Object> map : contorls) {
|
||||
|
||||
Class<?> cls = (Class<?>)map.get("className");
|
||||
Controller control = (Controller)map.get("annotation");
|
||||
|
||||
/*
|
||||
* 由于controller里只允许注入easybean,所以不需要等controller都创建好了再注入
|
||||
* 直接 迭代一次 就给一个controller注入一次
|
||||
*/
|
||||
Object obj = iocControl(cls,control,easyBeanObjs);
|
||||
|
||||
if(obj != null) {
|
||||
/* 获取controller的所有方法 */
|
||||
Method[] methods = cls.getMethods();
|
||||
for(Method method : methods) {
|
||||
EasyMapping easyMapping = method.getAnnotation(EasyMapping.class);
|
||||
if(easyMapping != null) {
|
||||
EasyMappingModel easyMappingModel = new EasyMappingModel();
|
||||
easyMappingModel.setObject(obj);
|
||||
easyMappingModel.setRequestMetohd(easyMapping.method());
|
||||
easyMappingModel.setMethod(method.getName());
|
||||
easyMappingModel.setCls(cls);
|
||||
controlObjects.put(easyMapping.value(), easyMappingModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constants.setAttr(EasyConstant.CONTROLLER_OBJECTS, controlObjects);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("加载controller并注入的时候报错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 往controller对象中注入easybean
|
||||
* @param cls lei
|
||||
* @param control kongzhi
|
||||
* @param easyBeanObjs duix
|
||||
* @return duix
|
||||
*/
|
||||
private static Object iocControl(Class<?> cls,Controller control,Map<String,EasyBeanModel> easyBeanObjs) throws Exception{
|
||||
|
||||
try {
|
||||
|
||||
MvcCglibProxy mvcCglibProxy = new MvcCglibProxy();
|
||||
Object obj = mvcCglibProxy.getProxy(cls);
|
||||
|
||||
/* 获取对象属性,完成注入 */
|
||||
Field[] fields = cls.getDeclaredFields();
|
||||
for(Field f : fields){
|
||||
Resource resource = f.getAnnotation(Resource.class);
|
||||
if(resource!=null){
|
||||
f.setAccessible(true);
|
||||
|
||||
String filedName = resource.value();
|
||||
if(filedName == null || filedName.equals("")) {
|
||||
filedName = f.getName();
|
||||
}
|
||||
|
||||
EasyBeanModel beanModel = easyBeanObjs.get(filedName);
|
||||
if(beanModel!=null){
|
||||
f.set(obj, beanModel.getObj());
|
||||
log.info(cls.getName()+"的属性"+f.getName()+"注入成功");
|
||||
}else{
|
||||
throw new Exception("不存在name为"+filedName+"的easyBean");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
throw new Exception("创建controller并注入的时候报错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的easybean
|
||||
* @return duix
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String,EasyBeanModel> getEasyBeans() {
|
||||
Object objs2 = constants.getAttr(EasyConstant.EASYBEAN_OBJECTS);
|
||||
Map<String,EasyBeanModel> easyBeanObjs = new HashMap<>();
|
||||
if(objs2 != null) {
|
||||
easyBeanObjs = (Map<String,EasyBeanModel>)objs2;
|
||||
}
|
||||
|
||||
return easyBeanObjs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.yuyenews.resolve;
|
||||
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
import com.yuyenews.easy.util.RequestUtil;
|
||||
import com.yuyenews.resolve.model.EasyMappingModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 解析请求
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ResolveRequest {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(ResolveRequest.class);
|
||||
|
||||
private static ResolveRequest resolveRequest;
|
||||
|
||||
private EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 执行器对象
|
||||
*/
|
||||
private ExecuteEasy executeEasy = ExecuteEasy.getExecuteEasy();
|
||||
|
||||
private ResolveRequest() {}
|
||||
|
||||
public static ResolveRequest getResolveRequest() {
|
||||
if(resolveRequest == null) {
|
||||
resolveRequest = new ResolveRequest();
|
||||
}
|
||||
return resolveRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解释请求,并调用对应的控制层方法进行处理
|
||||
* @param request qingqiu
|
||||
* @param response xiangying
|
||||
* @return duix
|
||||
*/
|
||||
public Object resolve(HttpRequest request,HttpResponse response) {
|
||||
|
||||
try {
|
||||
Map<String,EasyMappingModel> maps = getControllers();
|
||||
|
||||
String uri = getRequestPath(request);
|
||||
|
||||
return executeEasy.execute(maps.get(uri),request.getMethod(),request,response);
|
||||
} catch (Exception e) {
|
||||
log.error("解释请求的时候报错",e);
|
||||
}
|
||||
return MesUtil.getMes(500,"解析请求报错");
|
||||
}
|
||||
|
||||
/**
|
||||
* 从uri中提取 请求连接的最末端,用来匹配控制层映射
|
||||
* @param request qingqiu
|
||||
* @return
|
||||
*/
|
||||
private String getRequestPath(HttpRequest request) {
|
||||
/* 获取路径 */
|
||||
String uri = RequestUtil.getUriName(request);
|
||||
if(uri.startsWith("/")) {
|
||||
uri = uri.substring(1);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的controller对象
|
||||
* @return duix
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String,EasyMappingModel> getControllers() {
|
||||
|
||||
Map<String,EasyMappingModel> controlObjects = null;
|
||||
Object obj = constants.getAttr("controlObjects");
|
||||
if(obj != null) {
|
||||
controlObjects = (Map<String,EasyMappingModel>)obj;
|
||||
}
|
||||
|
||||
return controlObjects;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.yuyenews.resolve.model;
|
||||
|
||||
import com.yuyenews.core.annotation.enums.RequestMetohd;
|
||||
|
||||
/**
|
||||
* 控制器映射实体
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyMappingModel {
|
||||
|
||||
/**
|
||||
* 对象
|
||||
*/
|
||||
private Object object;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*/
|
||||
private RequestMetohd requestMetohd;
|
||||
|
||||
/**
|
||||
* 映射的方法
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 控制层class对象
|
||||
*/
|
||||
private Class<?> cls;
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public RequestMetohd getRequestMetohd() {
|
||||
return requestMetohd;
|
||||
}
|
||||
|
||||
public void setRequestMetohd(RequestMetohd requestMetohd) {
|
||||
this.requestMetohd = requestMetohd;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public void setCls(Class<?> cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.yuyenews.servlcet;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
import com.yuyenews.easy.server.servlet.EasyServlet;
|
||||
import com.yuyenews.resolve.ResolveRequest;
|
||||
|
||||
/**
|
||||
* 核心servlet,用于接收所有请求,并调用相应的方法进行处理
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyCoreServlet implements EasyServlet{
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(EasyCoreServlet.class);
|
||||
|
||||
@Override
|
||||
public Object doRequest(HttpRequest request, HttpResponse response) {
|
||||
try {
|
||||
|
||||
/* 将请求丢给解释器 去解释,并调用对应的控制层方法进行处理 */
|
||||
ResolveRequest resolveRequest = ResolveRequest.getResolveRequest();
|
||||
Object result = resolveRequest.resolve(request,response);
|
||||
|
||||
/*将控制层 返回的结果 返回给netty,让其响应给客户端*/
|
||||
return result;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("解释请求的时候报错",e);
|
||||
}
|
||||
return MesUtil.getMes(500,"解析请求报错");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-netty</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.yuyenews.easy.netty.server;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
|
||||
/**
|
||||
* netty服务
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyServer {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(EasyServer.class);
|
||||
|
||||
/**
|
||||
* 启动netty服务
|
||||
* @param portNumber
|
||||
*/
|
||||
public static void start(final int portNumber) {
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup();
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
try {
|
||||
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.group(bossGroup, workerGroup);
|
||||
b.channel(NioServerSocketChannel.class);
|
||||
b.childHandler(new EasyServerInitializer());
|
||||
|
||||
/* 服务器绑定端口监听 */
|
||||
ChannelFuture f = b.bind(portNumber).sync();
|
||||
|
||||
log.info("启动结束");
|
||||
|
||||
/* 监听服务器关闭监听 */
|
||||
f.channel().closeFuture().sync();
|
||||
} catch (Exception e) {
|
||||
log.error("启动netty报错",e);
|
||||
} finally {
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.yuyenews.easy.netty.server;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.netty.thread.RequestThread;
|
||||
import com.yuyenews.easy.netty.thread.ThreadPool;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
import io.netty.channel.ChannelHandlerAdapter;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* 接收netty服务
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyServerHandler extends ChannelHandlerAdapter {
|
||||
|
||||
private GogeLogger log = GogeLogger.getLogger(EasyServerHandler.class);
|
||||
|
||||
/**
|
||||
* 接收并处理 客户端请求
|
||||
*/
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
|
||||
FullHttpRequest httpRequest = null;
|
||||
|
||||
try {
|
||||
if (msg instanceof FullHttpRequest) {
|
||||
|
||||
httpRequest = (FullHttpRequest) msg;
|
||||
|
||||
/* 用新线程处理请求 */
|
||||
RequestThread requestThread = new RequestThread();
|
||||
requestThread.setHttpRequest(httpRequest);
|
||||
requestThread.setCtx(ctx);
|
||||
ThreadPool.execute(requestThread);
|
||||
} else {
|
||||
sendBad(ctx,"处理请求发生错误");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理请求失败!", e);
|
||||
sendBad(ctx,"处理请求发生错误"+e);
|
||||
|
||||
/* 已经通过线程中的finally 释放请求了,所以这里,在出异常的时候,才释放 */
|
||||
try {
|
||||
httpRequest.release();
|
||||
} catch (Exception e2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 建立连接时,返回消息
|
||||
*/
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
ctx.writeAndFlush("客户端" + InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! ");
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* 超时处理
|
||||
* @param ctx
|
||||
* @param evt
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if(evt instanceof IdleStateEvent){
|
||||
IdleStateEvent idleStateEvent = (IdleStateEvent)evt;
|
||||
|
||||
switch (idleStateEvent.state()){
|
||||
case READER_IDLE:
|
||||
sendTimeout(ctx,"请求超时");
|
||||
break;
|
||||
case WRITER_IDLE:
|
||||
sendTimeout(ctx,"请求超时");
|
||||
break;
|
||||
default:
|
||||
super.userEventTriggered(ctx, evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 响应
|
||||
* @param ctx
|
||||
*/
|
||||
private void sendBad(ChannelHandlerContext ctx,String ex){
|
||||
HttpResponse response = new HttpResponse(ctx);
|
||||
response.send(MesUtil.getMes(500,ex).toJSONString(), HttpResponseStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应请求超时
|
||||
* @param ctx
|
||||
*/
|
||||
private void sendTimeout(ChannelHandlerContext ctx,String ex){
|
||||
HttpResponse response = new HttpResponse(ctx);
|
||||
response.send(MesUtil.getMes(503,ex).toJSONString(), HttpResponseStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.yuyenews.easy.netty.server;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
|
||||
/**
|
||||
* 定义netty服务
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class EasyServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
private int timeOut = 10;
|
||||
private int maxContentLength = 10485760;
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
|
||||
/* 加载配置文件 */
|
||||
getConfig();
|
||||
|
||||
/* 处理http服务的关键handler */
|
||||
ChannelPipeline ph = ch.pipeline();
|
||||
ph.addLast("idlestatus", getIdleStateHandler());
|
||||
ph.addLast("encoder", new HttpResponseEncoder());
|
||||
ph.addLast("decoder", new HttpRequestDecoder());
|
||||
ph.addLast("aggregator", getHttpObjectAggregator());
|
||||
ph.addLast("handler", new EasyServerHandler());// 服务端业务逻辑
|
||||
}
|
||||
|
||||
|
||||
private IdleStateHandler getIdleStateHandler(){
|
||||
return new IdleStateHandler(timeOut,2000000000,0);
|
||||
}
|
||||
|
||||
private HttpObjectAggregator getHttpObjectAggregator(){
|
||||
return new HttpObjectAggregator(maxContentLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
* @return
|
||||
*/
|
||||
private void getConfig() {
|
||||
|
||||
JSONObject jsonObject = ConfigUtil.getConfig();
|
||||
Object timeOuto = jsonObject.get("timeOut");
|
||||
Object maxContentLengtho = jsonObject.get("maxContentLength");
|
||||
|
||||
if(timeOuto!=null) {
|
||||
timeOut = Integer.parseInt(timeOuto.toString());
|
||||
}
|
||||
|
||||
if(maxContentLengtho != null){
|
||||
maxContentLength = Integer.parseInt(maxContentLengtho.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.yuyenews.easy.netty.thread;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 处理请求的线程
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class RequestThread implements Runnable {
|
||||
|
||||
private GogeLogger log = GogeLogger.getLogger(RequestThread.class);
|
||||
|
||||
/**
|
||||
* netty的request对象
|
||||
*/
|
||||
private FullHttpRequest httpRequest;
|
||||
|
||||
private ChannelHandlerContext ctx;
|
||||
|
||||
public void setHttpRequest(FullHttpRequest httpRequest) {
|
||||
this.httpRequest = httpRequest;
|
||||
}
|
||||
|
||||
public void setCtx(ChannelHandlerContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
/* 组装httprequest对象 */
|
||||
HttpRequest request = new HttpRequest(httpRequest,ctx);
|
||||
|
||||
/* 组装httpresponse对象 */
|
||||
HttpResponse response = new HttpResponse(ctx);
|
||||
|
||||
try {
|
||||
|
||||
/* 获取全局存储空间 */
|
||||
EasySpace constants = EasySpace.getEasySpace();
|
||||
/* 从存储空间里获取核心servlet的全限名 */
|
||||
String className = constants.getAttr("core").toString();
|
||||
|
||||
/* 通过反射执行核心servlet */
|
||||
Class<?> cls = Class.forName(className);
|
||||
Object object = cls.getDeclaredConstructor().newInstance();
|
||||
Method helloMethod = cls.getDeclaredMethod("doRequest", new Class[] { HttpRequest.class ,HttpResponse.class});
|
||||
Object result = helloMethod.invoke(object, new Object[] { request ,response});
|
||||
if(result != null && result.toString().equals("void405cb55d6781877e9e930aa8e046098b")) {
|
||||
return;
|
||||
}
|
||||
/* 将控制层返回的数据,转成json字符串返回 */
|
||||
response.send(JSON.toJSONString(result));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理请求的时候出错",e);
|
||||
response.send(MesUtil.getMes(500,"处理请求发生错误"+e).toJSONString());
|
||||
} finally {
|
||||
// 释放请求
|
||||
httpRequest.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.yuyenews.easy.netty.thread;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 线程池,用于处理并发
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class ThreadPool {
|
||||
|
||||
private static BlockingQueue<Runnable> workQueue;
|
||||
|
||||
private static ThreadPoolExecutor pool;
|
||||
|
||||
private static int corePoolSize = 100;
|
||||
|
||||
private static int maximumPoolSize = 1000;
|
||||
|
||||
private static int keepAliveTime = 60;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 新增请求的线程
|
||||
* @param command
|
||||
*/
|
||||
public static void execute(Runnable command) {
|
||||
if(pool == null){
|
||||
init();
|
||||
workQueue = new ArrayBlockingQueue<>(maximumPoolSize - corePoolSize);
|
||||
pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize, keepAliveTime,TimeUnit.SECONDS,workQueue);
|
||||
}
|
||||
pool.execute(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取线程池的配置
|
||||
*/
|
||||
private static void init(){
|
||||
JSONObject jsonObject = ConfigUtil.getConfig();
|
||||
Object obj = jsonObject.get("threadPool");
|
||||
if(obj != null){
|
||||
JSONObject threadPool = JSONObject.parseObject(JSON.toJSONString(obj));
|
||||
|
||||
Object cs = threadPool.get("corePoolSize");
|
||||
Object mp = threadPool.get("maximumPoolSize");
|
||||
Object kt = threadPool.get("keepAliveTime");
|
||||
|
||||
if(cs != null){
|
||||
corePoolSize = Integer.parseInt(cs.toString());
|
||||
}
|
||||
if(mp != null){
|
||||
maximumPoolSize = Integer.parseInt(mp.toString());
|
||||
}
|
||||
if(kt != null){
|
||||
keepAliveTime = Integer.parseInt(kt.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>mars-server</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-ioc</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.yuyenews.easy.server.jwt;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTCreator;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JWT管理类
|
||||
*/
|
||||
public class JwtManager {
|
||||
/**
|
||||
* token秘钥
|
||||
*/
|
||||
private final String SECRET = "gogeframworkwinno1123456";
|
||||
/**
|
||||
* token 过期时间: 10天
|
||||
*/
|
||||
private final int calendarField = Calendar.DATE;
|
||||
private int calendarInterval = 10;
|
||||
|
||||
private static JwtManager jwtManager;
|
||||
private JwtManager(){}
|
||||
|
||||
public static JwtManager getJwtManager(){
|
||||
if(jwtManager == null){
|
||||
jwtManager = new JwtManager();
|
||||
jwtManager.loadCalendarInterval();
|
||||
}
|
||||
return jwtManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载配置文件中的jwt失效时间
|
||||
*/
|
||||
private void loadCalendarInterval(){
|
||||
JSONObject config = ConfigUtil.getConfig();
|
||||
Object jwtTime = config.get("jwtTime");
|
||||
|
||||
if(jwtTime != null){
|
||||
calendarInterval = Integer.parseInt(jwtTime.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WT生成Token.
|
||||
* @param obj
|
||||
* @return str
|
||||
*/
|
||||
public String createToken(Object obj) {
|
||||
Date iatDate = new Date();
|
||||
// expire time
|
||||
Calendar nowTime = Calendar.getInstance();
|
||||
nowTime.add(calendarField, calendarInterval);
|
||||
Date expiresDate = nowTime.getTime();
|
||||
|
||||
// header Map
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("alg", "HS256");
|
||||
map.put("typ", "JWT");
|
||||
|
||||
// header
|
||||
JWTCreator.Builder builder = JWT.create().withHeader(map);
|
||||
// payload
|
||||
|
||||
JSONObject json = JSONObject.parseObject(JSON.toJSONString(obj));
|
||||
|
||||
for (String key : json.keySet()) {
|
||||
builder.withClaim(key, json.get(key).toString());
|
||||
}
|
||||
|
||||
builder.withIssuedAt(iatDate); // sign time
|
||||
builder.withExpiresAt(expiresDate); // expire time
|
||||
String token = builder.sign(Algorithm.HMAC256(SECRET)); // signature
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验Token
|
||||
*
|
||||
* @param token
|
||||
* @return map
|
||||
*/
|
||||
public boolean verifyToken(String token) {
|
||||
Map<String, Claim> claims = decryptToken(token);
|
||||
return claims != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密Token
|
||||
*
|
||||
* @param token
|
||||
* @return map
|
||||
*/
|
||||
private Map<String, Claim> decryptToken(String token) {
|
||||
DecodedJWT jwt = null;
|
||||
try {
|
||||
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
|
||||
jwt = verifier.verify(token);
|
||||
return jwt.getClaims();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Token获取存进去的对象
|
||||
* @param token
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return obj
|
||||
*/
|
||||
public <T> T getObject(String token,Class<T> cls) {
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
Map<String, Claim> claims = decryptToken(token);
|
||||
for (String key : claims.keySet()) {
|
||||
json.put(key, claims.get(key).asString());
|
||||
}
|
||||
|
||||
return json.toJavaObject(cls);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.yuyenews.easy.server.request;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 全局对象,类似于tomcat的servletcontext
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class HttpContext {
|
||||
|
||||
private static HttpContext context;
|
||||
|
||||
private Map<String, Object> map = new ConcurrentHashMap<>();
|
||||
|
||||
private HttpContext() {
|
||||
}
|
||||
|
||||
public static HttpContext getHttpContext() {
|
||||
if (context == null) {
|
||||
context = new HttpContext();
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 往context里添加数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void setAttr(String key, Object value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从context里获取数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object getAttr(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package com.yuyenews.easy.server.request;
|
||||
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.easy.server.jwt.JwtManager;
|
||||
import com.yuyenews.easy.server.request.model.FileUpLoad;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 请求对象,对原生netty的request的补充
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class HttpRequest {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(HttpRequest.class);
|
||||
|
||||
/**
|
||||
* netty原生request
|
||||
*/
|
||||
private FullHttpRequest httpRequest;
|
||||
|
||||
/**
|
||||
* netty原生通道
|
||||
*/
|
||||
private ChannelHandlerContext ctx;
|
||||
|
||||
/**
|
||||
* 请求体
|
||||
*/
|
||||
private String body;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private Map<String, Object> paremeters;
|
||||
|
||||
/**
|
||||
* 请求的文件
|
||||
*/
|
||||
private Map<String,FileUpLoad> files;
|
||||
|
||||
/**
|
||||
* 构造函数,框架自己用的,程序员用不到,用了也没意义
|
||||
* @param httpRequest
|
||||
* @param ctx
|
||||
*/
|
||||
public HttpRequest(FullHttpRequest httpRequest,ChannelHandlerContext ctx) {
|
||||
this.body = getBody(httpRequest);
|
||||
this.setParameters(getParams(httpRequest));
|
||||
this.httpRequest = httpRequest;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求方法
|
||||
* @return 请求方法
|
||||
*/
|
||||
public HttpMethod getMethod() {
|
||||
return httpRequest.method();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要请求的uri
|
||||
* @return 请求方法
|
||||
*/
|
||||
public String getUri() {
|
||||
return httpRequest.uri();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头数据
|
||||
* @param key 键
|
||||
* @return 头数据
|
||||
*/
|
||||
public Object getHeader(String key) {
|
||||
return httpRequest.headers().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头
|
||||
* @return 请求头
|
||||
*/
|
||||
public HttpHeaders getHeaders() {
|
||||
return httpRequest.headers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的参数集
|
||||
* @return 请求参数
|
||||
*/
|
||||
public Map<String, Object> getParemeters() {
|
||||
return paremeters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装请求的参数
|
||||
* @param paremeters 请求参数
|
||||
*/
|
||||
private void setParameters(Map<String, Object> paremeters) {
|
||||
Object obj = paremeters.get("files");
|
||||
if (obj != null) {
|
||||
Map<String,FileUpLoad> files = (Map<String,FileUpLoad>) obj;
|
||||
this.files = files;
|
||||
paremeters.remove("files");
|
||||
}
|
||||
|
||||
this.paremeters = paremeters;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个请求的参数
|
||||
* @param key 键
|
||||
* @return 请求参数
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object getParemeter(String key) {
|
||||
Object objs = paremeters.get(key);
|
||||
if(objs != null) {
|
||||
List<Object> lis = (List<Object>)objs;
|
||||
return lis.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个请求的参数
|
||||
* @param key 键
|
||||
* @return 请求参数
|
||||
*/
|
||||
public List<Object> getParemeterValues(String key) {
|
||||
Object objs = paremeters.get(key);
|
||||
if(objs != null) {
|
||||
List<Object> lis = (List<Object>)objs;
|
||||
return lis;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的文件
|
||||
* @return 文件列表
|
||||
*/
|
||||
public Map<String,FileUpLoad> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个请求的文件
|
||||
*
|
||||
* @param name 名称
|
||||
* @return 单个文件
|
||||
*/
|
||||
public FileUpLoad getFile(String name) {
|
||||
if (files != null && files.size() > 0) {
|
||||
return files.get(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的url
|
||||
* @return 请求的路径
|
||||
*/
|
||||
public String getUrl() {
|
||||
return httpRequest.uri();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的body
|
||||
* @return 请求体
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取netty原生request
|
||||
* @return 原生请求对象
|
||||
*/
|
||||
public FullHttpRequest getFullHttpRequest() {
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取body参数
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return 请求体
|
||||
*/
|
||||
private String getBody(FullHttpRequest request) {
|
||||
ByteBuf buf = request.content();
|
||||
return buf.toString(CharsetUtil.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将GET, POST所有请求参数转换成Map对象
|
||||
* @param request 原生请求对象
|
||||
* @return 请求参数
|
||||
*/
|
||||
private Map<String, Object> getParams(FullHttpRequest request) {
|
||||
try {
|
||||
return new RequestParser(request).parse();
|
||||
} catch (Exception e) {
|
||||
logger.error("从请求中获取参数,报错",e);
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JWT管理类对象
|
||||
* @return jwt
|
||||
*/
|
||||
public JwtManager getJwtManager(){
|
||||
return JwtManager.getJwtManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP
|
||||
* @return ip
|
||||
*/
|
||||
public String getIp() {
|
||||
String clientIP = String.valueOf(httpRequest.headers().get("X-Forwarded-For"));
|
||||
if (clientIP == null || clientIP.equals("null")) {
|
||||
InetSocketAddress insocket = (InetSocketAddress) this.ctx.channel().remoteAddress();
|
||||
clientIP = insocket.getAddress().getHostAddress();
|
||||
}
|
||||
return clientIP;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.yuyenews.easy.server.request;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
import com.yuyenews.core.util.FileUtil;
|
||||
import com.yuyenews.core.util.MesUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.*;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 响应对象,对netty原生response的扩展
|
||||
* <p>
|
||||
* 暂时没有提供response的支持
|
||||
*
|
||||
* @author yuye
|
||||
*/
|
||||
public class HttpResponse {
|
||||
|
||||
private GogeLogger logger = GogeLogger.getLogger(HttpResponse.class);
|
||||
|
||||
/**
|
||||
* netty原生通道
|
||||
*/
|
||||
private ChannelHandlerContext ctx;
|
||||
|
||||
/**
|
||||
* 响应头
|
||||
*/
|
||||
private Map<String, String> header;
|
||||
|
||||
|
||||
/**
|
||||
* 构造函数,框架自己用的,程序员用不到,用了也没意义
|
||||
*
|
||||
* @param ctx netty原生通道
|
||||
*/
|
||||
public HttpResponse(ChannelHandlerContext ctx) {
|
||||
this.ctx = ctx;
|
||||
this.header = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取netty原生通道
|
||||
* @return netty原生通道
|
||||
*/
|
||||
public ChannelHandlerContext getChannelHandlerContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置响应头
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void setHeader(String key, String value) {
|
||||
this.header.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*
|
||||
* @param context 消息
|
||||
*/
|
||||
public void send(String context) {
|
||||
send(context, HttpResponseStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*
|
||||
* @param context 消息
|
||||
* @param status 状态
|
||||
*/
|
||||
public void send(String context, HttpResponseStatus status) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status,
|
||||
Unpooled.copiedBuffer(context, CharsetUtil.UTF_8));
|
||||
|
||||
crossDomain(response);
|
||||
|
||||
if (header != null) {
|
||||
for (String key : header.keySet()) {
|
||||
response.headers().set(key, header.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/json; charset=UTF-8");
|
||||
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param file 要下载的文件
|
||||
*/
|
||||
public void sendFile(File file) {
|
||||
try{
|
||||
setHeader("Content-Length", String.valueOf(file.length()));
|
||||
sendFile(FileUtil.getFileToByte(file),file.getName());
|
||||
} catch (Exception e){
|
||||
logger.error("将流文件流响应给客户端出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param file 要下载的文件
|
||||
*/
|
||||
public void sendFile(InputStream file,String fileName) {
|
||||
sendFile(FileUtil.getInputStreamToByte(file),fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param file 要下载的文件
|
||||
*/
|
||||
public void sendFile(BufferedImage file, String fileName){
|
||||
sendFile(FileUtil.getBufferedImageToByte(file),fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param file 要下载的文件
|
||||
*/
|
||||
public void sendFile(byte[] file,String fileName) {
|
||||
try{
|
||||
|
||||
if(file == null){
|
||||
if(this.header.get("Content-Length") != null){
|
||||
this.header.remove("Content-Length");
|
||||
}
|
||||
send(MesUtil.getMes(404,"要下载的文件不存在").toJSONString());
|
||||
throw new Exception("要下载的文件不存在");
|
||||
}
|
||||
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(file));
|
||||
|
||||
crossDomain(response);
|
||||
|
||||
if (header != null) {
|
||||
for (String key : header.keySet()) {
|
||||
response.headers().set(key, header.get(key));
|
||||
}
|
||||
}
|
||||
response.headers().set("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(),"UTF-8"));
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/octet-stream; charset=UTF-8");
|
||||
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||
} catch (Exception e){
|
||||
logger.error("将流文件流响应给客户端出错",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置跨域
|
||||
*/
|
||||
private void crossDomain(FullHttpResponse response) {
|
||||
JSONObject jsonObject = getConfig();
|
||||
Object object = jsonObject.get("cross_domain");
|
||||
if (object != null) {
|
||||
JSONObject ob = JSONObject.parseObject(JSON.toJSONString(object));
|
||||
|
||||
response.headers().set("Access-Control-Allow-Origin", ob.get("origin").toString());
|
||||
response.headers().set("Access-Control-Allow-Methods", ob.get("methods").toString());
|
||||
response.headers().set("Access-Control-Max-Age", ob.get("maxAge").toString());
|
||||
response.headers().set("Access-Control-Allow-Headers", ob.get("headers").toString());
|
||||
response.headers().set("Access-Control-Allow-Credentials", ob.get("credentials").toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置文件
|
||||
*
|
||||
* @return 配置文件对象
|
||||
*/
|
||||
private JSONObject getConfig() {
|
||||
JSONObject jsonObject = ConfigUtil.getConfig();
|
||||
if (jsonObject != null) {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return new JSONObject();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.yuyenews.easy.server.request;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.yuyenews.easy.server.request.model.FileUpLoad;
|
||||
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import io.netty.handler.codec.http.multipart.Attribute;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
|
||||
import io.netty.handler.codec.http.multipart.MixedFileUpload;
|
||||
|
||||
/**
|
||||
* 参数解析器
|
||||
*
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class RequestParser {
|
||||
|
||||
private FullHttpRequest fullReq;
|
||||
|
||||
/**
|
||||
* 构造一个解析器
|
||||
*
|
||||
* @param req 请求对象
|
||||
*/
|
||||
public RequestParser(FullHttpRequest req) {
|
||||
this.fullReq = req;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析请求参数
|
||||
*
|
||||
* @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map
|
||||
*
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> parse() throws Exception {
|
||||
HttpMethod method = fullReq.method();
|
||||
|
||||
Map<String, Object> parmMap = new HashMap<>();
|
||||
|
||||
if (HttpMethod.GET == method) {
|
||||
// 是GET请求
|
||||
QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
|
||||
Map<String, List<String>> params = decoder.parameters();
|
||||
for(String key : params.keySet()){
|
||||
parmMap.put(key, params.get(key));
|
||||
}
|
||||
} else if (HttpMethod.POST == method) {
|
||||
// 是POST请求
|
||||
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq);
|
||||
decoder.offer(fullReq);
|
||||
|
||||
List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
|
||||
|
||||
Map<String, FileUpLoad> files = new Hashtable<>();
|
||||
|
||||
for (InterfaceHttpData parm : parmList) {
|
||||
|
||||
if (parm instanceof Attribute) {
|
||||
Attribute data = (Attribute) parm;
|
||||
List<Object> ps = null;
|
||||
Object objs = parmMap.get(data.getName());
|
||||
if (objs == null) {
|
||||
ps = new ArrayList<>();
|
||||
} else {
|
||||
ps = (List<Object>) objs;
|
||||
}
|
||||
ps.add(data.getValue());
|
||||
parmMap.put(data.getName(), ps);
|
||||
|
||||
} else if (parm instanceof MixedFileUpload) {
|
||||
MixedFileUpload fileUpload = (MixedFileUpload) parm;
|
||||
|
||||
byte[] bs = fileUpload.get();
|
||||
|
||||
InputStream inputStream = new ByteArrayInputStream(bs);
|
||||
|
||||
FileUpLoad upLoad = new FileUpLoad();
|
||||
upLoad.setFileName(fileUpload.getFilename());
|
||||
upLoad.setInputStream(inputStream);
|
||||
upLoad.setName(fileUpload.getName());
|
||||
|
||||
files.put(fileUpload.getName(), upLoad);
|
||||
}
|
||||
|
||||
}
|
||||
parmMap.put("files", files);
|
||||
}
|
||||
|
||||
return parmMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.yuyenews.easy.server.request.model;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 文件参数实体类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class FileUpLoad {
|
||||
|
||||
/**
|
||||
* 请求name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 文件流
|
||||
*/
|
||||
private InputStream inputStream;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public void setInputStream(InputStream inputStream) {
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yuyenews.easy.server.servlet;
|
||||
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
import com.yuyenews.easy.server.request.HttpResponse;
|
||||
|
||||
/**
|
||||
* servlet 模板
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public interface EasyServlet {
|
||||
|
||||
|
||||
/**
|
||||
* 请求接受方法
|
||||
* @param request
|
||||
* @param response
|
||||
* @return obj
|
||||
*/
|
||||
Object doRequest(HttpRequest request,HttpResponse response);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.yuyenews.easy.util;
|
||||
|
||||
import com.yuyenews.easy.server.request.HttpRequest;
|
||||
|
||||
/**
|
||||
* 请求工具类
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class RequestUtil {
|
||||
|
||||
/**
|
||||
* 从uri中提取最末端
|
||||
* @param request 请求
|
||||
* @return string
|
||||
*/
|
||||
public static String getUriName(HttpRequest request) {
|
||||
/* 获取路径 */
|
||||
String uri = request.getUri();
|
||||
if(uri.indexOf("?")>-1) {
|
||||
uri = uri.substring(0,uri.indexOf("?"));
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-start</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-start-base</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-jdbc-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-mvc</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.yuyenews.start.base;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yuyenews.core.after.StartAfter;
|
||||
import com.yuyenews.core.constant.EasyConstant;
|
||||
import com.yuyenews.core.constant.EasySpace;
|
||||
import com.yuyenews.core.load.LoadClass;
|
||||
import com.yuyenews.core.logger.GogeLogger;
|
||||
import com.yuyenews.core.util.ConfigUtil;
|
||||
import com.yuyenews.easy.netty.server.EasyServer;
|
||||
import com.yuyenews.ioc.load.LoadEasyBean;
|
||||
import com.yuyenews.jdbc.base.BaseInitJdbc;
|
||||
import com.yuyenews.resolve.LoadController;
|
||||
import com.yuyenews.servlcet.EasyCoreServlet;
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class BaseStartEasy {
|
||||
|
||||
private static GogeLogger log = GogeLogger.getLogger(BaseStartEasy.class);
|
||||
|
||||
/**
|
||||
* 获取全局存储空间
|
||||
*/
|
||||
private static EasySpace constants = EasySpace.getEasySpace();
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @param clazz
|
||||
*/
|
||||
public static void start(Class<?> clazz, BaseInitJdbc baseInitJdbc) {
|
||||
try {
|
||||
|
||||
log.info("程序启动中......");
|
||||
|
||||
/* 加载框架数据 */
|
||||
load(clazz,baseInitJdbc);
|
||||
|
||||
/* 标识createbean方法已经调用完毕 */
|
||||
constants.setAttr(EasyConstant.HAS_START,"yes");
|
||||
|
||||
/* 启动after方法 */
|
||||
StartAfter.after();
|
||||
|
||||
/* 启动netty */
|
||||
EasyServer.start(getPort());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载控制层所有的类和所需数据
|
||||
*/
|
||||
private static void load(Class<?> clazz, BaseInitJdbc baseInitJdbc) throws Exception{
|
||||
|
||||
/* 配置核心servlet */
|
||||
constants.setAttr("core", EasyCoreServlet.class.getName());
|
||||
|
||||
/* 加载配置文件 */
|
||||
ConfigUtil.loadConfig();
|
||||
|
||||
/*获取要扫描的包*/
|
||||
String className = clazz.getName();
|
||||
className = className.substring(0,className.lastIndexOf("."));
|
||||
|
||||
/* 将要扫描的包名存到全局存储空间,给别的需要的地方使用 */
|
||||
constants.setAttr("rootPath", className);
|
||||
|
||||
/* 获取此包下面的所有类(包括jar中的) */
|
||||
LoadClass.loadBeans(className);
|
||||
|
||||
/* 加载JDBC模块 */
|
||||
if(baseInitJdbc != null){
|
||||
baseInitJdbc.init();
|
||||
}
|
||||
|
||||
/* 创建bean对象 */
|
||||
LoadEasyBean.loadBean();
|
||||
|
||||
/* 创建controller对象 */
|
||||
LoadController.loadContrl();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取端口号,默认8080
|
||||
* @return
|
||||
*/
|
||||
private static int getPort() {
|
||||
|
||||
JSONObject jsonObject = ConfigUtil.getConfig();
|
||||
Object por = jsonObject.get("port");
|
||||
if(por!=null) {
|
||||
return Integer.parseInt(por.toString());
|
||||
}
|
||||
|
||||
return 8080;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#此配置文件只是个demo,对开发没什么卵用
|
||||
|
||||
#配置端口号(默认8080)
|
||||
port: 8088
|
||||
#配置jwt有效期(默认1),单位:天
|
||||
jwtTime: 20
|
||||
#请求超时时间(默认10),单位:秒
|
||||
timeOut: 10
|
||||
#请求数据的最大值(默认10485760)
|
||||
maxContentLength: 10
|
||||
#配置跨域请求
|
||||
cross_domain:
|
||||
origin: *
|
||||
methods: "GET,POST"
|
||||
maxAge: 9
|
||||
headers: "x-requested-with,Cache-Control,Pragma,Content-Type,Token"
|
||||
credentials: "true"
|
||||
|
||||
|
||||
#配置处理请求的线程池参数(这些都是默认值)
|
||||
threadPool:
|
||||
corePoolSize: 100
|
||||
maximumPoolSize: 1000
|
||||
keepAliveTime: 60
|
||||
|
||||
#配置持久层
|
||||
jdbc:
|
||||
#配置数据源,必须是数组
|
||||
dataSource:
|
||||
-
|
||||
name: dataSource
|
||||
url: jdbc:mysql://10.211.55.5:3306/test?serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: rootroot
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
|
||||
#配置mybatis方言
|
||||
dialect: mysql
|
||||
#配置要扫描的mapper.xml 文件存放路径
|
||||
mappers: mappers
|
||||
|
||||
#log4j2 配置文件的路径
|
||||
#相对路径必须以classPath- 开头,区分大小写
|
||||
#绝对路径直接写即可,不需要开头
|
||||
logFile: classpath-log4j2.xml
|
||||
|
||||
|
||||
#以下配置 必须在导入goge-extends 中的相应的jar包后 才生效
|
||||
|
||||
#redis配置
|
||||
redis:
|
||||
maxTotal: 1000
|
||||
maxIdle: 100
|
||||
numTestsPerEvictionRun: 10
|
||||
timeBetweenEvictionRunsMillis: 10
|
||||
minEvictableIdleTimeMillis: 10
|
||||
softMinEvictableIdleTimeMillis: 10
|
||||
maxWaitMillis: 10
|
||||
testOnBorrow: false
|
||||
testWhileIdle: false
|
||||
testOnReturn: false
|
||||
jmxEnabled: false
|
||||
jmxNamePrefix: pool
|
||||
blockWhenExhausted: false
|
||||
# redis连接,必须是数组 因为可能需要连多个redis
|
||||
jedisShardInfos:
|
||||
-
|
||||
name: master
|
||||
host: 10.211.55.5
|
||||
port: 6379
|
||||
password: 123456
|
||||
# 这两个可以不配置
|
||||
connectionTimeout: 1000
|
||||
soTimeout: 1000
|
||||
|
||||
#邮件配置 只支持smtp
|
||||
mail:
|
||||
host: smtp.sina.com
|
||||
port: 465
|
||||
smtpSslEnable: true
|
||||
debug: false
|
||||
# 发件箱
|
||||
sendMail: 发件箱
|
||||
sendMailPwd: 发件箱密码
|
||||
auth: true
|
||||
@@ -0,0 +1,10 @@
|
||||
#此配置文件只是个demo,对开发没什么卵用
|
||||
|
||||
#配置端口号(默认8080)
|
||||
port: 8088
|
||||
|
||||
#goge-config 远程配置中心
|
||||
config:
|
||||
name: user1
|
||||
myIp: 127.0.0.1
|
||||
url: 127.0.0.1:8090
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-start</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-start-jpa</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-start-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-jpa</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.yuyenews.start;
|
||||
|
||||
import com.yuyenews.easy.jpa.init.InitJdbc;
|
||||
import com.yuyenews.start.base.BaseStartEasy;
|
||||
|
||||
public class StartEasy {
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @param clazz
|
||||
*/
|
||||
public static void start(Class<?> clazz){
|
||||
BaseStartEasy.start(clazz,new InitJdbc());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-start</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-start-mybatis</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-start-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-mybatis</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.yuyenews.start;
|
||||
|
||||
import com.yuyenews.easy.init.InitJdbc;
|
||||
import com.yuyenews.start.base.BaseStartEasy;
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class StartEasy {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @param clazz
|
||||
*/
|
||||
public static void start(Class<?> clazz) {
|
||||
BaseStartEasy.start(clazz,new InitJdbc());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mars-start</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mars-start-simple</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-start-base</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.yuyenews.start;
|
||||
|
||||
import com.yuyenews.start.base.BaseStartEasy;
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @author yuye
|
||||
*
|
||||
*/
|
||||
public class StartEasy {
|
||||
|
||||
/**
|
||||
* 启动easy框架
|
||||
* @param clazz
|
||||
*/
|
||||
public static void start(Class<?> clazz) {
|
||||
BaseStartEasy.start(clazz,null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>mars-start-mybatis</module>
|
||||
<module>mars-start-simple</module>
|
||||
<module>mars-start-jpa</module>
|
||||
<module>mars-start-base</module>
|
||||
</modules>
|
||||
<artifactId>mars-start</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,178 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>Mars-java</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>mars-aop</module>
|
||||
<module>mars-ioc</module>
|
||||
<module>mars-core</module>
|
||||
<module>mars-mvc</module>
|
||||
<module>mars-netty</module>
|
||||
<module>mars-server</module>
|
||||
<module>mars-start</module>
|
||||
<module>mars-jdbc</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<javadocExecutable>${java.home}/../bin/javadoc</javadocExecutable>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-aop</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-ioc</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-mvc</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-netty</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.gitee.sherlockholmnes</groupId>
|
||||
<artifactId>mars-server</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>5.0.0.Alpha2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.47</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>3.2.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.11</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.4.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>4.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jyaml</groupId>
|
||||
<artifactId>jyaml</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
<artifactId>oss-parent</artifactId>
|
||||
<version>7</version>
|
||||
</parent>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<url>https://gitee.com/SherlockHolmnes/Goge-framework</url>
|
||||
<connection>https://gitee.com/SherlockHolmnes/Goge-framework.git</connection>
|
||||
<developerConnection>https://gitee.com/SherlockHolmnes/Goge-framework</developerConnection>
|
||||
</scm>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>sherlockholmes</name>
|
||||
<email>1784955689@qq.com</email>
|
||||
<url>https://gitee.com/SherlockHolmnes/Goge-framework</url>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Reference in New Issue
Block a user