Skip to content

Commit 58f514a

Browse files
authored
Merge pull request #24 from codingapi/dev
Dev
2 parents d7fd2c6 + 2f47e80 commit 58f514a

File tree

11 files changed

+227
-6
lines changed

11 files changed

+227
-6
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<groupId>com.codingapi.springboot</groupId>
1414
<artifactId>springboot-parent</artifactId>
15-
<version>2.1.0</version>
15+
<version>2.1.1</version>
1616

1717
<url>https://github.com/codingapi/springboot-framewrok</url>
1818
<name>springboot-parent</name>

springboot-starter-data-fast/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>springboot-parent</artifactId>
77
<groupId>com.codingapi.springboot</groupId>
8-
<version>2.1.0</version>
8+
<version>2.1.1</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

springboot-starter-id-generator/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>springboot-parent</artifactId>
77
<groupId>com.codingapi.springboot</groupId>
8-
<version>2.1.0</version>
8+
<version>2.1.1</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

springboot-starter-security-jwt/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<artifactId>springboot-parent</artifactId>
88
<groupId>com.codingapi.springboot</groupId>
9-
<version>2.1.0</version>
9+
<version>2.1.1</version>
1010
</parent>
1111

1212
<artifactId>springboot-starter-security-jwt</artifactId>

springboot-starter/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>com.codingapi.springboot</groupId>
77
<artifactId>springboot-parent</artifactId>
8-
<version>2.1.0</version>
8+
<version>2.1.1</version>
99
</parent>
1010
<artifactId>springboot-starter</artifactId>
1111

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.codingapi.springboot.framework.domain.field;
2+
3+
import com.codingapi.springboot.framework.event.IEvent;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import lombok.ToString;
7+
8+
/**
9+
* 实体字段变更事件
10+
*/
11+
@Setter
12+
@Getter
13+
@ToString(exclude = {"entity"})
14+
public class FieldChangeEvent implements IEvent {
15+
16+
/**
17+
* 实体对象
18+
*/
19+
private Object entity;
20+
21+
/**
22+
* 实体类名称
23+
*/
24+
private String simpleName;
25+
26+
/**
27+
* 时间戳
28+
*/
29+
private long timestamp;
30+
31+
/**
32+
* 字段名称
33+
*/
34+
private String fieldName;
35+
/**
36+
* 旧的值
37+
*/
38+
private Object oldValue;
39+
/**
40+
* 新的值
41+
*/
42+
private Object newValue;
43+
44+
45+
46+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.codingapi.springboot.framework.domain.field;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
5+
/**
6+
* 实体代理工厂
7+
*/
8+
public class FieldProxyFactory {
9+
10+
public static <T> T create(Class<T> entityClass, Object... args) {
11+
FieldValueInterceptor interceptor = null;
12+
try {
13+
interceptor = new FieldValueInterceptor(entityClass, args);
14+
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
15+
throw new RuntimeException(e);
16+
}
17+
return (T) interceptor.createProxy();
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package com.codingapi.springboot.framework.domain.field;
2+
3+
import com.codingapi.springboot.framework.event.EventPusher;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.beans.BeanUtils;
6+
import org.springframework.cglib.proxy.Enhancer;
7+
import org.springframework.cglib.proxy.MethodInterceptor;
8+
import org.springframework.cglib.proxy.MethodProxy;
9+
10+
import java.beans.PropertyDescriptor;
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.lang.reflect.Method;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
16+
/**
17+
* 实体代理
18+
*/
19+
@Slf4j
20+
public class FieldValueInterceptor implements MethodInterceptor {
21+
22+
// 目标类
23+
private final Class<?> targetClass;
24+
// 目标类构造函数参数类型
25+
private final Class<?>[] parameterTypes;
26+
// 目标类构造函数参数
27+
private final Object[] args;
28+
29+
// 目标类实例
30+
private final Object target;
31+
// 目标类属性描述
32+
private final PropertyDescriptor[] propertyDescriptors;
33+
// 目标类属性值
34+
private final Map<String, Object> fields;
35+
36+
public FieldValueInterceptor(Class<?> targetClass, Object... args) throws NoSuchMethodException,
37+
InvocationTargetException, InstantiationException, IllegalAccessException {
38+
this.targetClass = targetClass;
39+
this.args = args;
40+
this.parameterTypes = new Class<?>[args.length];
41+
for (int i = 0; i < args.length; i++) {
42+
parameterTypes[i] = args[i].getClass();
43+
}
44+
this.target = targetClass.getConstructor(parameterTypes).newInstance(args);
45+
this.propertyDescriptors = BeanUtils.getPropertyDescriptors(targetClass);
46+
this.fields = new HashMap<>();
47+
}
48+
49+
50+
/**
51+
* 创建代理
52+
* @return 代理对象
53+
*/
54+
public Object createProxy() {
55+
Enhancer enhancer = new Enhancer();
56+
enhancer.setSuperclass(targetClass);
57+
enhancer.setCallback(this);
58+
return enhancer.create(parameterTypes, args);
59+
}
60+
61+
62+
/**
63+
* 拦截方法
64+
* @param obj 代理对象
65+
* @param method 方法
66+
* @param args 参数
67+
* @param proxy 代理
68+
* @return 方法返回值
69+
* @throws Throwable 异常
70+
*/
71+
@Override
72+
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
73+
// 更新函数肯定有参数,如果没有参数,直接返回
74+
if (method.getParameterCount() <= 0) {
75+
return method.invoke(target, args);
76+
}
77+
78+
if(fields.isEmpty()){
79+
this.readFields();
80+
}
81+
Object result = method.invoke(target, args);
82+
this.compareAndUpdateField();
83+
return result;
84+
}
85+
86+
/**
87+
* 读取Entity字段
88+
* @throws InvocationTargetException InvocationTargetException
89+
* @throws IllegalAccessException InvocationTargetException
90+
*/
91+
private void readFields() throws InvocationTargetException, IllegalAccessException {
92+
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
93+
String name = propertyDescriptor.getName();
94+
Object value = propertyDescriptor.getReadMethod().invoke(target);
95+
fields.put(name, value);
96+
}
97+
}
98+
99+
/**
100+
* 对比字段
101+
* @throws InvocationTargetException InvocationTargetException
102+
* @throws IllegalAccessException InvocationTargetException
103+
*/
104+
private void compareAndUpdateField() throws InvocationTargetException, IllegalAccessException {
105+
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
106+
String name = propertyDescriptor.getName();
107+
Object newValue = propertyDescriptor.getReadMethod().invoke(target);
108+
Object oldValue = fields.get(name);
109+
if (!newValue.equals(oldValue)) {
110+
pushEvent(name, oldValue, newValue);
111+
}
112+
fields.put(name, newValue);
113+
}
114+
}
115+
116+
private void pushEvent(String field, Object oldValue, Object newValue) {
117+
FieldChangeEvent event = new FieldChangeEvent();
118+
event.setEntity(target);
119+
event.setSimpleName(targetClass.getSimpleName());
120+
event.setFieldName(field);
121+
event.setOldValue(oldValue);
122+
event.setNewValue(newValue);
123+
event.setTimestamp(System.currentTimeMillis());
124+
EventPusher.push(event);
125+
}
126+
}

springboot-starter/src/test/java/com/codingapi/springboot/framework/domain/Demo.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Demo implements JsonSerializable, MapSerializable {
1010

1111
@Getter
1212
private long id;
13+
1314
@Getter
1415
private String name;
1516

@@ -21,7 +22,7 @@ public Demo(String name) {
2122
public void changeName(String name) {
2223
String beforeName = this.name;
2324
this.name = name;
24-
//push event
25+
// push event
2526
EventPusher.push(new DemoChangeEvent(beforeName, name));
2627
}
2728

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.codingapi.springboot.framework.domain;
2+
3+
import com.codingapi.springboot.framework.domain.field.FieldProxyFactory;
4+
import org.junit.jupiter.api.Test;
5+
import org.springframework.boot.test.context.SpringBootTest;
6+
7+
@SpringBootTest
8+
class FieldProxyFactoryTest {
9+
10+
@Test
11+
void createEntity() {
12+
Demo demo = FieldProxyFactory.create(Demo.class, "test");
13+
demo.changeName("123");
14+
}
15+
}

0 commit comments

Comments
 (0)