Commit 12e93ff6 authored by duanledexianxianxian's avatar duanledexianxianxian 😁

init

parent 259741fc
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.26" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.17.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.9.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.26" level="project" />
</component>
</module>
\ No newline at end of file
......@@ -9,33 +9,29 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kafka</artifactId>
<artifactId>demo</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.duanledexianxianxian.demo;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 代码生成器
*/
public class CodeGenerator {
/**
* 读取控制台内容
*
* @param tip the tip
* @return the string
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
/**
* The entry point of application.
*
* @param args the input arguments
*/
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
// 项目路径
String projectPath = "F:/@project@/@dianli@/springboot-demo/demo";
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("duanledexianxianxian");
gc.setOpen(false);
gc.setFileOverride(true);
gc.setBaseResultMap(true);
gc.setBaseColumnList(true);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://rm-bp1451sz2b7q8w95xvo.mysql.rds.aliyuncs.com:3306/convention?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("convention");
dsc.setPassword("Convention123");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模块名"));
pc.setParent("com.duanledexianxianxian.demo");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
// strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
// 写于父类中的公共字段
// strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
package com.duanledexianxianxian.demo.common.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* BeanUtil提供一系列与bean相关的操作.
*
* @author duanledexianxianxian
* @date 2019-02-14 23:35:22
*/
public class BeanUtils extends org.springframework.beans.BeanUtils {
/**
* The constant logger.
*/
private static Logger logger = LoggerFactory.getLogger(BeanUtils.class);
/**
* The constant SERIAL_VERSION_UID.
*/
private static final String SERIAL_VERSION_UID = "serialVersionUID";
/**
* The constant COMPARE_TYPE_INTEGER.
*/
private static final String COMPARE_TYPE_INTEGER = "java.lang.Integer";
/**
* The constant COMPARE_TYPE_STRING.
*/
private static final String COMPARE_TYPE_STRING = "java.lang.String";
/**
* Copy properties.
*
* @param source the source
* @param target the target
* @throws BeansException the beans exception
*/
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);
}
/**
* Copy properties.
*
* @param source the source
* @param target the target
* @param editable the editable
* @param ignoreProperties the ignore properties
* @throws BeansException the beans exception
*/
private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)
throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName()
+ "] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
boolean ignoreCondition = ignoreList == null || !ignoreList.contains(targetPd.getName());
if (writeMethod != null && ignoreCondition) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
boolean isAssignable = ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType());
if (readMethod != null && isAssignable) {
try {
setReadMethod(readMethod);
Object value = readMethod.invoke(source);
// 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等
setWriteMethodMethod(value, writeMethod, target);
} catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
}
/**
* Sets read method.
*
* @param readMethod the read method
*/
private static void setReadMethod(Method readMethod) {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
}
/**
* Sets write method method.
*
* @param value the value
* @param writeMethod the write method
* @param target the target
* @throws Exception the exception
*/
private static void setWriteMethodMethod(Object value, Method writeMethod, Object target) throws Exception {
if (value != null) {
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
}
/**
* 复制对象.
*
* @param <T> the type parameter
* @param entity the entity
* @param targetCls the target cls
* @return the t
*/
public static <T> T copyObject(Object entity, Class<? extends T> targetCls) {
// 如果entity,直接返回null
if (entity == null) {
return null;
}
Object target = null;
try {
target = targetCls.newInstance();
copyProperties(entity, target);
} catch (InstantiationException | IllegalAccessException e) {
logger.error("error:{}", e);
}
return (T) target;
}
/**
* 复制对象
*
* @param list the list
* @param targetCls the target cls
* @return list list
*/
public static List copyList(List list, Class<?> targetCls) {
List resultList = new ArrayList();
if (list != null && list.size() > 0) {
for (Object entity : list) {
resultList.add(copyObject(entity, targetCls));
}
}
return resultList;
}
/**
* java反射bean的get方法
*
* @param objectClass the object class
* @param fieldName the field name
* @return get method
*/
@SuppressWarnings("unchecked")
public static Method getGetMethod(Class objectClass, String fieldName) {
StringBuffer sb = new StringBuffer();
sb.append("get");
sb.append(fieldName.substring(0, 1).toUpperCase());
sb.append(fieldName.substring(1));
try {
return objectClass.getMethod(sb.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
logger.error("error:{}", e);
}
return null;
}
/**
* java反射bean的set方法
*
* @param objectClass the object class
* @param fieldName the field name
* @return set method
*/
@SuppressWarnings("unchecked")
public static Method getSetMethod(Class objectClass, String fieldName) {
try {
Class[] parameterTypes = new Class[1];
Field field = objectClass.getDeclaredField(fieldName);
parameterTypes[0] = field.getType();
StringBuffer sb = new StringBuffer();
sb.append("set");
sb.append(fieldName.substring(0, 1).toUpperCase());
sb.append(fieldName.substring(1));
Method method = objectClass.getMethod(sb.toString(), parameterTypes);
return method;
} catch (Exception e) {
e.printStackTrace();
logger.error("error:{}", e);
}
return null;
}
/**
* 执行set方法
*
* @param o 执行对象
* @param fieldName 属性
* @param value 值
*/
public static void invokeSet(Object o, String fieldName, Object value) {
Method method = getSetMethod(o.getClass(), fieldName);
try {
method.invoke(o, new Object[]{value});
} catch (Exception e) {
e.printStackTrace();
logger.error("error:{}", e);
}
}
/**
* 这个函数主要用于将字符串和数字型分开 前台都是字符串 根据model类型转换 现在仅支持String int 不是这两个类型不做set函数<br>.
*
* @param o the o
* @param fieldName the field name
* @param value the value
*/
public static void invokeSetStringInt(Object o, String fieldName, String value) {
Method method = getGetMethod(o.getClass(), fieldName);
String type = method.getReturnType().getName();
if (COMPARE_TYPE_INTEGER.equals(type)) {
invokeSet(o, fieldName, (value == null) ? null : Integer.parseInt(value));
} else if (COMPARE_TYPE_STRING.equals(type)) {
invokeSet(o, fieldName, value);
} else {
logger.error("set 函数不能设置Sting和int以外的函数,设置类型:" + type + ",方法:" + method.getName());
}
}
/**
* 执行get方法
*
* @param o 执行对象
* @param fieldName 属性
* @return the object
*/
public static Object invokeGet(Object o, String fieldName) {
Method method = getGetMethod(o.getClass(), fieldName);
try {
return method.invoke(o, new Object[0]);
} catch (Exception e) {
e.printStackTrace();
logger.error("error:{}", e);
}
return null;
}
/**
* 将返回值包装成String 如果是空则仍然保持空.
*
* @param o the o
* @param fieldName the field name
* @return the string
*/
public static String invokeGetString(Object o, String fieldName) {
Object obj = invokeGet(o, fieldName);
return (obj == null) ? null : String.valueOf(obj);
}
/**
* Merger obj object.
*
* @param <T> 项目域对象如果为空,则直接返回产品域对象项目域对象字段属性为空,则使用产品域覆盖项目域字段
* @param parent 产品域对象
* @param son 项目域对象
* @param refClass class对象
* @return the object
*/
public static <T> Object mergerObj(T parent, T son, Class<?> refClass) {
Object obj = null;
try {
obj = refClass.newInstance();
if (parent == null) {
obj = son;
} else if (son == null) {
obj = parent;
} else {
for (Field field : refClass.getDeclaredFields()) {
String fieldName = field.getName();
if (SERIAL_VERSION_UID.equalsIgnoreCase(fieldName)) {
continue;
}
Object value = invokeGet(son, fieldName);
if (value == null) {
value = invokeGet(parent, fieldName);
}
invokeSet(obj, fieldName, value);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("error:{}", e);
}
logger.debug("Page object:" + obj);
return obj;
}
/**
* Merger obj object.
*
* @param <T> the type parameter
* @param parent the parent
* @param son the son
* @param refClassParent the ref class parent
* @param refClassSon the ref class son
* @return the object
*/
public static <T> Object mergerObj(T parent, T son, Class<?> refClassParent, Class<?> refClassSon) {
return mergerObj(parent, son, refClassParent, refClassSon, null);
}
/**
* Merger obj object.
*
* @param <T> 父对象为空,则直接返回子对象<br>
* 子对象为空,则将子对象域父对象相同的字段拷贝给obj<br>
* 父对象与子对象都不为空,现将子对象的值拷贝给obj,在将子对象与父对象相同的字段拷贝给obj<br>
* 例如:比如指标与业务视图字段合并,则指标为父对象、业务视图字段为子对象变量命名有问题<br>
* @param parent 父对象
* @param son 子对象
* @param refClassParent 父class对象
* @param refClassSon 子class对象
* @param prefix 前缀
* @return the object
*/
public static <T> Object mergerObj(T parent, T son, Class<?> refClassParent,
Class<?> refClassSon, String prefix) {
Map<String, String> publicFieldMap = new HashMap<>(100);
Object obj = null;
try {
//比较父class对象与子class对象,找出字段相同的字段
for (Field pField : refClassParent.getDeclaredFields()) {
for (Field sField : refClassSon.getDeclaredFields()) {
if (sField.getName().equals(pField.getName())) {
publicFieldMap.put(pField.getName(), sField.getName());
break;
} else if (prefix != null && sField.getName().equals(prefix + pField.getName())) {
publicFieldMap.put(pField.getName(), sField.getName());
break;
}
}
}
obj = refClassSon.newInstance();
//父对象为空,直接返回父对象给obj
if (parent == null) {
obj = son;
} else
//子对象为空,将父对象中与子对象中相同字段的值复制给obj
if (son == null) {
for (Map.Entry<String, String> entry : publicFieldMap.entrySet()) {
if (SERIAL_VERSION_UID.equalsIgnoreCase(entry.getValue())) {
continue;
}
Object value = invokeGet(parent, entry.getValue());
invokeSet(obj, entry.getValue(), value);
}
} else {
//先将子对象拷贝给obj
for (Field field : refClassSon.getDeclaredFields()) {
if (SERIAL_VERSION_UID.equalsIgnoreCase(field.getName())) {
continue;
}
Object value = invokeGet(son, field.getName());
invokeSet(obj, field.getName(), value);
}
//将相同字段的值拷贝给obj
for (Map.Entry<String, String> entry : publicFieldMap.entrySet()) {
String pFieldName = entry.getKey();
if (SERIAL_VERSION_UID.equalsIgnoreCase(entry.getValue())) {
continue;
}
Object value = invokeGet(son, entry.getValue());
if (null == value || "".equals(value)) {
value = invokeGet(parent, pFieldName);
}
invokeSet(obj, entry.getValue(), value);
}
}
} catch (Exception e) {
logger.error("error:{}", e);
}
return obj;
}
/**
* Division obj t.
*
* @param <T> the type parameter
* @param parent 父对象
* @param son 子对象
* @param newSon 新的子对象
* @param refClass class对象
* @return T t
*/
public static <T> T divisionObj(T parent, T son, T newSon, Class<?> refClass) {
return divisionObj(parent, son, newSon, refClass, "");
}
/**
* 比较产品域对象、项目域对象、页面对象,返回最后需要插入数据库中的对象
*
* @param <T> the type parameter
* @param parent 父对象
* @param son 子对象
* @param newSon 新的子对象
* @param refClass class对象
* @param excludeFields 不需要比较字段的列表
* @return T t
*/
public static <T> T divisionObj(T parent, T son, T newSon, Class<?> refClass, String... excludeFields) {
for (Field field : refClass.getDeclaredFields()) {
if (SERIAL_VERSION_UID.equalsIgnoreCase(field.getName())) {
continue;
}
//排除不需要比较的字段
if (!"".equals(excludeFields) && Arrays.asList(excludeFields).contains(field.getName())) {
continue;
}
/*项目域不存在,则说明该元素只是项目化没有修改,表里面不存在*/
Object valueSon = (son == null) ? null : invokeGet(son, field.getName());
/*子对象的对应的属性为空,则继承与产品域的属性,如果没有修改则继续继承*/
if (valueSon == null) {
Object valueNewSon = invokeGet(newSon, field.getName());
Object valueParent = invokeGet(parent, field.getName());
if (valueParent != null && valueParent.equals(valueNewSon)) {
invokeSet(newSon, field.getName(), null);
}
}
}
return newSon;
}
/**
* 应用场景,产品域字段列表跟项目域字段列表合并,以keyName作为主键,相同的keyName,则使用项目域的覆盖产品域的
*
* @param <T> the type parameter
* @param parentList 父域列表
* @param sonList 子域列表
* @param keyName 主键
* @return list list
*/
public static <T> List<T> mergerList(List<T> parentList, List<T> sonList, String keyName) {
List<T> resultList = new ArrayList<T>();
Map<Object, T> map = new HashMap<>(100);
if (parentList == null) {
resultList.addAll(sonList);
return resultList;
}
if (sonList == null) {
resultList.addAll(parentList);
return resultList;
}
resultList.addAll(parentList);
for (T obj : parentList) {
Object keyFieldName = invokeGet(obj, keyName);
map.put(keyFieldName, obj);
}
int size = sonList.size();
for (int i = 0; i < size; i++) {
Object keyFieldName = invokeGet(sonList.get(i), keyName);
if (map.containsKey(keyFieldName)) {
resultList.remove(map.get(keyFieldName));
resultList.add(i, sonList.get(i));
} else {
resultList.add(sonList.get(i));
}
}
return resultList;
}
/**
* 返回dto的所有属性字段名称 返回其中所有字段(除serialVersionUID之外) 可以用于设置值.
*
* @param <T> the type parameter
* @param refClass the ref class
* @return the string [ ]
*/
public static <T> String[] getAllFieldName(Class<?> refClass) {
Field[] allField = refClass.getDeclaredFields();
List<String> allFieldList = new ArrayList<String>();
for (int i = 0, j = 0; i < allField.length; i++) {
String filedName = allField[i].getName();
if (!SERIAL_VERSION_UID.equalsIgnoreCase(filedName)) {
allFieldList.add(filedName);
}
}
return allFieldList.toArray(new String[allFieldList.size()]);
}
/**
* 返回dto的所有Field字段 返回其中所有字段(除serialVersionUID之外) 可以用于设置值.
*
* @param <T> the type parameter
* @param refClass the ref class
* @return the field [ ]
*/
public static <T> Field[] getAllField(Class<?> refClass) {
Field[] allField = refClass.getDeclaredFields();
List<Field> allFieldList = new ArrayList<Field>();
for (int i = 0, j = 0; i < allField.length; i++) {
if (!SERIAL_VERSION_UID.equalsIgnoreCase(allField[i].getName())) {
allFieldList.add(allField[i]);
}
}
return allFieldList.toArray(new Field[allFieldList.size()]);
}
/**
* 获取指定字段名称查找在class中的对应的Field对象(包括查找父类)
*
* @param clazz 指定的class
* @param fieldName 字段名称
* @return Field对象 class field
*/
public static Field getClassField(Class clazz, String fieldName) {
if (!Object.class.getName().equals(clazz.getName())) {
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
if (field.getName().equals(fieldName)) {
return field;
}
}
Class superClass = clazz.getSuperclass();
if (superClass != null) {
// 简单的递归一下
return getClassField(superClass, fieldName);
}
}
return null;
}
}
package com.duanledexianxianxian.demo.domain.dto;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 菜单传输对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class MenuDTO implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* 菜单编号
*/
private Long menuId;
/**
* 菜单url
*/
private String menuUrl;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单编码
*/
private String menuCode;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
package com.duanledexianxianxian.demo.domain.dto;
import com.duanledexianxianxian.demo.domain.entity.Menu;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
/**
* 用户传输对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class UserDTO implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* 用户编号
*/
private Long userId;
/**
* 用户名称
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 年龄
*/
private Integer age;
/**
* 生日
*/
private LocalDate birthday;
/**
* 菜单列表
*/
List<MenuDTO> menuList;
}
package com.duanledexianxianxian.demo.domain.model.query;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 菜单表单对象
*
* @author duanledexianxianxian
* @since 2020-03-19
*/
@Data
public class MenuForm implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户编号
*/
private Long userId;
/**
* 菜单编号
*/
private Long menuId;
/**
* 菜单url
*/
private String menuUrl;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单编码
*/
private String menuCode;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
package com.duanledexianxianxian.demo.domain.model.query;
import lombok.Data;
import java.io.Serializable;
/**
* 菜单查询对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class MenuQuery implements Serializable {
/**
* 菜单名称
*/
private String menuName;
}
package com.duanledexianxianxian.demo.domain.model.query;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
/**
* 用户表单对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class UserForm implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* 用户编号
*/
private Long userId;
/**
* 用户名称
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 年龄
*/
private Integer age;
/**
* 生日
*/
private LocalDate birthday;
}
package com.duanledexianxianxian.demo.domain.model.query;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
/**
* 用户查询对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class UserQuery implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* The Page num.
*/
Long pageNum=1L;
/**
* The Page size.
*/
Long pageSize=10L;
/**
* 用户名称
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
}
package com.duanledexianxianxian.demo.domain.model.vo;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 菜单vo对象
*
* @author duanledexianxianxian
* @since 2020-03-19
*/
@Data
public class MenuVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 菜单编号
*/
private Long menuId;
/**
* 菜单url
*/
private String menuUrl;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单编码
*/
private String menuCode;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
package com.duanledexianxianxian.demo.domain.model.vo;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
/**
* 用户vo对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class UserDetailVO implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* 用户编号
*/
private Long userId;
/**
* 用户名称
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 年龄
*/
private Integer age;
/**
* 生日
*/
private LocalDate birthday;
/**
* The Menu list.
*/
private List<MenuVO> menuList;
}
package com.duanledexianxianxian.demo.domain.model.vo;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
/**
* 用户vo对象
*
* @author duanledexianxianxian
* @since 2020 -03-19
*/
@Data
public class UserVO implements Serializable {
/**
* The constant serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* 用户编号
*/
private Long userId;
/**
* 用户名称
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 年龄
*/
private Integer age;
/**
* 生日
*/
private LocalDate birthday;
}
##### kafka配置
```
bootstrap.servers:kafka server的地址
acks:写入kafka时,leader负责一个该partion读写,当写入partition时,需要将记录同步到repli节点,all是全部同步节点都返回成功,leader才返回ack。
retris:写入失败时,重试次数。当leader节点失效,一个repli节点会替代成为leader节点,此时可能出现写入失败,当retris为0时,produce不会重复。retirs重发,此时repli节点完全成为leader节点,不会产生消息丢失。
batch.size:produce积累到一定数据,一次发送。
buffer.memory: produce积累数据一次发送,缓存大小达到buffer.memory就发送数据。
linger.ms :当设置了缓冲区,消息就不会即时发送,如果消息总不够条数、或者消息不够buffer大小就不发送了吗?当消息超过linger时间,也会发送。
key/value serializer:序列化类。
```
### 关于kafka序列化/反序列化
https://www.jianshu.com/p/5da86afed228
自定义Serializer和Deserializer非常痛苦,还有很多类型不支持,非常脆弱。复杂类型的支持更是一件痛苦的事情,不同版本之间的兼容性问题更是一个极大的挑战。由于Serializer和Deserializer影响到上下游系统,导致牵一发而动全身。自定义序列化&反序列化实现不是能力的体现,而是逗比的体现。所以强烈不建议自定义实现序列化&反序列化,推荐直接使用StringSerializer和StringDeserializer,然后使用json作为标准的数据传输格式。
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.kafka:spring-kafka:2.2.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-messaging:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.kafka:kafka-clients:2.0.1" level="project" />
<orderEntry type="library" name="Maven: org.lz4:lz4-java:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.xerial.snappy:snappy-java:1.1.7.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.56" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.kafka:spring-kafka-test:2.2.7.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.kafka:kafka-clients:test:2.0.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.kafka:kafka_2.11:2.0.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.9" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.sf.jopt-simple:jopt-simple:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.yammer.metrics:metrics-core:2.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.scala-lang:scala-library:2.11.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.scala-lang:scala-reflect:2.11.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.typesafe.scala-logging:scala-logging_2.11:3.9.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.101tec:zkclient:0.10" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.zookeeper:zookeeper:3.4.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.yetus:audience-annotations:0.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.kafka:kafka_2.11:test:2.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.26" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.21" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.17.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.9.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.8.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.26" level="project" />
</component>
</module>
\ No newline at end of file
package com.duanledexianxianxian.demo.kafka;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author duanledexianxianxian
* @date 2019/10/18 23:32
* @since 1.0.0
*/
@SpringBootApplication
@Slf4j
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.duanledexianxianxian.demo.kafka.consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
/**
* kafka消费者测试
*
* @author fengyuchenglun
* @version 1.0.0
*/
@Component
public class TestConsumer {
/**
* Listen.
*
* @param record the record
* @throws Exception the exception
*/
@KafkaListener(topics = "topic_second")
public void listen(ConsumerRecord<?, ?> record) throws Exception {
System.out.printf("topic = %s, offset = %d, value = %s \n", record.topic(), record.offset(), record.value());
}
}
package com.duanledexianxianxian.demo.kafka.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author duanledexianxianxian
* @date 2019/10/18 23:50
* @since 1.0.0
*/
@RestController
public class KafkaController {
@Autowired
private KafkaTemplate<String,Object> kafkaTemplate;
@GetMapping("/message/send")
public boolean send(@RequestParam String message){
kafkaTemplate.send("testTopic",message);
return true;
}
}
package com.duanledexianxianxian.demo.kafka.listener;
import com.alibaba.fastjson.JSONObject;
import com.duanledexianxianxian.demo.kafka.model.Student;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.*;
/**
* @author duanledexianxianxian
* @date 2019/10/19 0:44
* @since 1.0.0
*/
@Component
@Slf4j
public class AppListener implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder().namingPattern("producer-kafka-pool-%d").daemon(true).build();
ExecutorService pool = new ThreadPoolExecutor(5, 200,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
int i = 0;
while (true) {
int finalI = i;
pool.execute(() -> {
this.sendData(finalI);
// sleep 5 seconds
});
try {
Thread.sleep(new Random().nextInt(6) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
private void sendData(int i) {
Student student = new Student();
student.setStudentId(String.valueOf(i));
student.setName("duanledexianxianxian" + new Random().nextInt(20));
student.setAge(new Random().nextInt(19) + 6);
student.setSex(Byte.valueOf(String.valueOf((new Random().nextInt(2)))));
log.info("Thread:{} Send Data:{}", Thread.currentThread().getName(), student);
kafkaTemplate.send("topic_first", JSONObject.toJSONString(student));
}
}
package com.duanledexianxianxian.demo.kafka.model;
import lombok.Data;
import java.io.Serializable;
/**
* 学生实体类
*
* @author duanledexianxianxian
* @date 2019/10/19 0:32
* @since 1.0.0
*/
@Data
public class Student implements Serializable {
private static final long serialVersionUID = -4572819276161640638L;
/**
* 学生学号
*/
private String studentId;
/**
* 学生姓名
*/
private String name;
/**
* 学生年龄
*/
private Integer age;
/**
* 学生性别
* 0-男
* 1-女
*/
private Byte sex;
}
spring:
kafka:
# 指定kafka server的地址,集群配多个,中间,逗号隔开
bootstrap-servers: 113.105.144.9:9104
#=============== provider =======================
producer:
# 写入失败时,重试次数。当leader节点失效,一个repli节点会替代成为leader节点,此时可能出现写入失败,
# 当retris为0时,produce不会重复。retirs重发,此时repli节点完全成为leader节点,不会产生消息丢失。
retries: 0
# 每次批量发送消息的数量,produce积累到一定数据,一次发送
batch-size: 16384
# produce积累数据一次发送,缓存大小达到buffer.memory就发送数据
buffer-memory: 33554432
# 指定消息key和消息体的编解码方式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
properties:
#当设置了缓冲区,消息就不会即时发送,如果消息总不够条数、或者消息不够buffer大小就不发送了吗?当消息超过linger时间,也会发送。
linger.ms: 1
#procedure要求leader在考虑完成请求之前收到的确认数,用于控制发送记录在服务端的持久化,其值可以为如下:
#acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。
#acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。
#acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。
#可以设置的值为:all, -1, 0, 1
acks: 1
#=============== consumer =======================
consumer:
group-id: test
# enable.auto.commit:true --> 设置自动提交offset
enable-auto-commit: true
# auto-commit'为true,则消费者偏移自动提交给Kafka的频率(以毫秒为单位),默认值为5000。:
auto-commit-interval: 100ms
# 指定消息key和消息体的编解码方式
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
properties:
session.timeout.ms: 15000
\ No newline at end of file
<?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>demo-parent</artifactId>
<groupId>com.duanledexianxianxian.demo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>menu</artifactId>
</project>
\ No newline at end of file
package com.duanledexianxianxian.demo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author duanledexianxianxian
* @date 2020/1/12 23:51
* @since 1.0.0
*/
public class Application {
private static String[][] menus = {
{null, "0001", "用户管理", "/urlMgr"},
{"0001", "00010001", "用户管理-添加用户", "/urlMgr/add"},
{"0001", "00010002", "用户管理-修改用户", "/urlMgr/edit"},
{"0001", "00010003", "用户管理-删除用户", "/urlMgr/delete"},
{"0001", "00010004", "用户管理-查询用户", "/urlMgr/query"},
{null, "0002", "系统管理", "/systemMgr"},
{"0002", "00020001", "系统管理-系统管理0001", "/systemMgr/0001"},
{"00020001", "000200010001", "系统管理-系统管理0001-系统管理0001", "/systemMgr/0001/0001"},
{"000200010001", "0002000100010001", "系统管理-系统管理0001-系统管理0001-系统管理0001", "/systemMgr/0001/0001/0001"},
};
public static void main(String[] args) {
List<Menu> menuList = Lists.newArrayList();
Arrays.asList(menus).forEach(x -> {
Menu menu = new Menu();
menu.setParentMenuCode(x[0]);
menu.setMenuCode(x[1]);
menu.setMenuTitle(x[2]);
menu.setMenuUrl(x[3]);
menuList.add(menu);
});
menuList.forEach(x -> System.out.println(x.toString()));
MenuVO menuVO = getTreeMenuVO(menuList);
ObjectMapper mapper = new ObjectMapper();
try {
System.out.println(mapper.writeValueAsString(menuVO));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
/**
* 平级列表转成树结构
* @param menuList
* @return
*/
private static MenuVO getTreeMenuVO(List<Menu> menuList) {
if (CollectionUtils.isEmpty(menuList)) {
return null;
}
List<MenuVO> menuVOList = Lists.newArrayList();
// 类型转换 一层循环
menuList.forEach(x -> {
MenuVO menuVO = new MenuVO();
BeanUtils.copyProperties(x, menuVO);
menuVOList.add(menuVO);
});
// 转成map 二层循环 一层与二层可以合并
Map<String, MenuVO> menuMap = menuVOList.stream().collect(Collectors.toMap(MenuVO::getMenuCode, x -> x));
// 构建根节点
MenuVO menuVO = new MenuVO();
menuVO.setParentMenuCode(null);
menuVO.setMenuCode("root");
menuVO.setMenuTitle("根节点");
// 转换逻辑 三层循环
for (MenuVO menu : menuVOList) {
if (menuMap.containsKey(menu.getParentMenuCode())) {
if (menuMap.get(menu.getParentMenuCode()).getChildren() == null) {
menuMap.get(menu.getParentMenuCode()).setChildren(Lists.newArrayList());
}
menuMap.get(menu.getParentMenuCode()).getChildren().add(menu);
} else {
if (menuVO.getChildren() == null) {
menuVO.setChildren(Lists.newArrayList());
}
menuVO.getChildren().add(menu);
}
}
return menuVO;
}
}
package com.duanledexianxianxian.demo;
import lombok.Data;
/**
* 菜单
*
* @author duanledexianxianxian
* @date 2020/1/12 23:49
* @since 1.0.0
*/
@Data
public class Menu {
private String parentMenuCode;
private String menuCode;
private String menuTitle;
private String menuUrl;
}
package com.duanledexianxianxian.demo;
import lombok.Data;
import java.util.List;
/**
* 菜单
*
* @author duanledexianxianxian
* @date 2020/1/12 23:49
* @since 1.0.0
*/
@Data
public class MenuVO {
private String parentMenuCode;
private String menuCode;
private String menuTitle;
private String menuUrl;
private List<MenuVO> children;
}
......@@ -9,32 +9,23 @@
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>kafka</module>
<module>menu</module>
<module>demo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<version>2.1.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
......@@ -46,7 +37,54 @@
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
</dependencies>
<properties>
<java.version>1.8</java.version>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment