Browse Source

增加新增和修改事件

zhou-hao 6 years ago
parent
commit
16f4678360

+ 13 - 0
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/events/EntityCreatedEvent.java

@@ -0,0 +1,13 @@
+package org.hswebframework.web.commons.entity.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.io.Serializable;
+
+@AllArgsConstructor
+@Getter
+public class EntityCreatedEvent<E> implements Serializable{
+
+    private E entity;
+}

+ 16 - 0
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/events/EntityModifyEvent.java

@@ -0,0 +1,16 @@
+package org.hswebframework.web.commons.entity.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.io.Serializable;
+
+@AllArgsConstructor
+@Getter
+public class EntityModifyEvent<E> implements Serializable{
+
+    private E before;
+
+    private E after;
+
+}

+ 49 - 3
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java

@@ -18,17 +18,20 @@
 
 package org.hswebframework.web.service;
 
+import lombok.Setter;
 import org.hswebframework.web.commons.entity.GenericEntity;
 import org.hswebframework.web.commons.entity.LogicalDeleteEntity;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.commons.entity.RecordModifierEntity;
-import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.commons.entity.events.EntityCreatedEvent;
+import org.hswebframework.web.commons.entity.events.EntityModifyEvent;
 import org.hswebframework.web.id.IDGenerator;
-import org.hswebframework.web.validator.DuplicateKeyException;
-import org.hswebframework.web.validator.LogicPrimaryKeyValidator;
 import org.hswebframework.web.validator.group.CreateGroup;
 import org.hswebframework.web.validator.group.UpdateGroup;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.PayloadApplicationEvent;
+import org.springframework.core.ResolvableType;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 import org.springframework.util.CollectionUtils;
@@ -61,6 +64,13 @@ public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
      */
     protected abstract IDGenerator<PK> getIDGenerator();
 
+    protected ApplicationEventPublisher eventPublisher;
+
+    @Autowired(required = false)
+    public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
+        this.eventPublisher = eventPublisher;
+    }
+
     @PostConstruct
     public void init() {
         if (logicPrimaryKeyValidator instanceof DefaultLogicPrimaryKeyValidator) {
@@ -89,13 +99,37 @@ public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
         return old;
     }
 
+    protected boolean pushModifyEvent() {
+        return RecordModifierEntity.class.isAssignableFrom(entityType);
+    }
+
+    protected boolean pushCreatedEvent() {
+        return RecordCreationEntity.class.isAssignableFrom(entityType);
+    }
+
     @Override
     public int updateByPk(PK pk, E entity) {
         Assert.notNull(pk, "primary key can not be null");
         Assert.hasText(String.valueOf(pk), "primary key can not be null");
         Assert.notNull(entity, "entity can not be null");
         entity.setId(pk);
+
         tryValidate(entity, UpdateGroup.class);
+        //实现了 RecordModifierEntity接口的实体,将推送 EntityModifyEvent 事件.
+        if (eventPublisher != null && pushModifyEvent()) {
+            E old = selectByPk(pk);
+
+            EntityModifyEvent<?> e = new EntityModifyEvent<>(old, entity);
+            PayloadApplicationEvent<EntityModifyEvent<?>> event = new PayloadApplicationEvent<EntityModifyEvent<?>>(this, e) {
+                @Override
+                public ResolvableType getResolvableType() {
+                    return ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class
+                            , ResolvableType.forClassWithGenerics(EntityModifyEvent.class, entityType));
+                }
+            };
+
+            eventPublisher.publishEvent(event);
+        }
         return createUpdate(entity)
                 //如果是RecordCreationEntity则不修改creator_id和creator_time
                 .when(entity instanceof RecordCreationEntity,
@@ -152,6 +186,18 @@ public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
         }
         tryValidate(entity, CreateGroup.class);
         getDao().insert(entity);
+
+        if (eventPublisher != null && pushCreatedEvent()) {
+            EntityCreatedEvent<?> e = new EntityCreatedEvent<>(entity);
+            PayloadApplicationEvent<EntityCreatedEvent<?>> event = new PayloadApplicationEvent<EntityCreatedEvent<?>>(this, e) {
+                @Override
+                public ResolvableType getResolvableType() {
+                    return ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class
+                            , ResolvableType.forClassWithGenerics(EntityModifyEvent.class, entityType));
+                }
+            };
+            eventPublisher.publishEvent(event);
+        }
         return entity.getId();
     }
 

+ 2 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/EnableCacheTests.java

@@ -106,6 +106,8 @@ public class EnableCacheTests {
         doTest(enableCacheAllEvictTreeTestService);
     }
 
+
+
     public void doTest(CrudService<TestEntity, String> service) {
         service.selectByPk("testId"); //db 1
         service.selectByPk("testId");//cache

+ 2 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/GenericEntityServiceTest.java

@@ -13,6 +13,8 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
 
 import javax.validation.Validation;
 import java.util.ArrayList;
@@ -40,7 +42,6 @@ public class GenericEntityServiceTest {
     public void init() {
         entityService.setEntityFactory(new MapperEntityFactory());
         entityService.setValidator(Validation.buildDefaultValidatorFactory().getValidator());
-
         TestEntity entity = TestEntity.builder()
                 .age((byte) 10)
                 .enabled(true)

+ 85 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/ModifyEventTests.java

@@ -0,0 +1,85 @@
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.entity.events.EntityModifyEvent;
+import org.hswebframework.web.commons.entity.factory.MapperEntityFactory;
+import org.hswebframework.web.dao.CrudDao;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * @author zhouhao
+ * @since 3.0
+ */
+@SpringBootTest(classes = SpringTestApplication.class)
+@RunWith(value = SpringRunner.class)
+@Component
+public class ModifyEventTests {
+
+    @Autowired
+    private TestModifyEntityService modifyEntityService;
+
+    private AtomicInteger counter = new AtomicInteger();
+
+    @Before
+    public void init() {
+        CrudDao<TestModifyEntity, String> dao = Mockito.mock(CrudDao.class);
+        modifyEntityService.setEntityFactory(new MapperEntityFactory());
+        modifyEntityService.setDao(dao);
+        TestModifyEntity entity = TestModifyEntity.builder()
+                .age((byte) 10)
+                .enabled(true)
+                .name("test")
+                .build();
+        entity.setId("testId");
+
+        when(dao.query(any()))
+                .then((Answer<List<TestModifyEntity>>) invocationOnMock -> {
+                    //模拟命中数据库
+                    counter.incrementAndGet();
+                    return new ArrayList<>(Arrays.asList(entity));
+                });
+
+        when(dao.count(any())).then((Answer<Integer>) invocationOnMock -> {
+            //模拟命中数据库
+            counter.incrementAndGet();
+            return 1;
+        });
+
+        when(dao.update(any())).thenReturn(1);
+
+        when(dao.delete(any())).thenReturn(1);
+        when(dao.deleteByPk(anyString())).thenReturn(1);
+
+        doNothing().when(dao).insert(anyObject());
+
+    }
+
+
+    @Test
+    public void modifyTest() {
+        TestModifyEntity entity = new TestModifyEntity();
+        entity.setId("testId");
+        entity.setAge((byte) 10);
+
+        modifyEntityService.updateByPk("test", entity);
+        Assert.assertTrue(TestModifyEntityService.eventCounter.get() != 0);
+    }
+
+
+}

+ 9 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/TestEntity.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.service;
 
 import lombok.*;
 import org.hibernate.validator.constraints.NotBlank;
+import org.hswebframework.web.commons.entity.RecordModifierEntity;
 import org.hswebframework.web.commons.entity.SimpleGenericEntity;
 import org.hswebframework.web.commons.entity.SimpleTreeSortSupportEntity;
 import org.hswebframework.web.validator.LogicPrimaryKey;
@@ -18,7 +19,9 @@ import java.util.List;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class TestEntity extends SimpleTreeSortSupportEntity<String> {
+public class TestEntity extends SimpleTreeSortSupportEntity<String>
+//        implements RecordModifierEntity
+{
 
     @NotBlank(groups = CreateGroup.class)
     private String name;
@@ -28,4 +31,9 @@ public class TestEntity extends SimpleTreeSortSupportEntity<String> {
     private Boolean enabled;
 
     private List<TestEntity> children;
+
+    private String modifierId;
+
+    private Long modifyTime;
+
 }

+ 37 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/TestModifyEntity.java

@@ -0,0 +1,37 @@
+package org.hswebframework.web.service;
+
+import lombok.*;
+import org.hibernate.validator.constraints.NotBlank;
+import org.hswebframework.web.commons.entity.RecordModifierEntity;
+import org.hswebframework.web.commons.entity.SimpleTreeSortSupportEntity;
+import org.hswebframework.web.validator.group.CreateGroup;
+
+import java.util.List;
+
+/**
+ * @author zhouhao
+ * @since 1.0
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TestModifyEntity extends SimpleTreeSortSupportEntity<String>
+        implements RecordModifierEntity
+{
+
+    @NotBlank(groups = CreateGroup.class)
+    private String name;
+
+    private Byte age;
+
+    private Boolean enabled;
+
+    private List<TestModifyEntity> children;
+
+    private String modifierId;
+
+    private Long modifyTime;
+
+}

+ 37 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/TestModifyEntity2.java

@@ -0,0 +1,37 @@
+package org.hswebframework.web.service;
+
+import lombok.*;
+import org.hibernate.validator.constraints.NotBlank;
+import org.hswebframework.web.commons.entity.RecordModifierEntity;
+import org.hswebframework.web.commons.entity.SimpleTreeSortSupportEntity;
+import org.hswebframework.web.validator.group.CreateGroup;
+
+import java.util.List;
+
+/**
+ * @author zhouhao
+ * @since 1.0
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TestModifyEntity2 extends SimpleTreeSortSupportEntity<String>
+        implements RecordModifierEntity
+{
+
+    @NotBlank(groups = CreateGroup.class)
+    private String name;
+
+    private Byte age;
+
+    private Boolean enabled;
+
+    private List<TestModifyEntity2> children;
+
+    private String modifierId;
+
+    private Long modifyTime;
+
+}

+ 44 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/test/java/org/hswebframework/web/service/TestModifyEntityService.java

@@ -0,0 +1,44 @@
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.entity.RecordModifierEntity;
+import org.hswebframework.web.commons.entity.events.EntityModifyEvent;
+import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.id.IDGenerator;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author zhouhao
+ * @since 3.0
+ */
+@Service
+public class TestModifyEntityService extends GenericEntityService<TestModifyEntity, String> {
+
+    private CrudDao<TestModifyEntity, String> dao;
+
+    public static AtomicLong eventCounter = new AtomicLong();
+
+    @Override
+    protected IDGenerator<String> getIDGenerator() {
+        return IDGenerator.MD5;
+    }
+
+    @Override
+    public CrudDao<TestModifyEntity, String> getDao() {
+        return dao;
+    }
+
+    public void setDao(CrudDao<TestModifyEntity, String> dao) {
+        this.dao = dao;
+    }
+
+    @EventListener
+    public void handleEvent(EntityModifyEvent<TestModifyEntity> modifyEvent){
+        eventCounter.incrementAndGet();
+        System.out.println(modifyEvent);
+    }
+
+}