zhouhao 8 rokov pred
rodič
commit
8e3c103d9e
46 zmenil súbory, kde vykonal 698 pridanie a 83 odobranie
  1. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/HttpTokenRequest.java
  2. 1 1
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java
  3. 2 2
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/SimpleAuthorizeMethodInterceptor.java
  4. 1 1
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java
  5. 1 1
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java
  6. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DatabaseType.java
  7. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java
  8. 1 1
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupportEntity.java
  9. 1 1
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/factory/MapperEntityFactory.java
  10. 1 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java
  11. 1 1
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java
  12. 9 9
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/AbstactLocakManager.java
  13. 16 2
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/LockManager.java
  14. 4 4
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/SimpleLockManager.java
  15. 65 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/Lock.java
  16. 64 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/ReadLock.java
  17. 60 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/WriteLock.java
  18. 9 10
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-redis/src/main/java/org/hswebframework/web/concurrent/lock/redis/RedissonLockManager.java
  19. 16 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/pom.xml
  20. 99 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/AopLockAdvisor.java
  21. 8 3
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/LockFactoryAutoConfiguration.java
  22. 120 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/LockProcessor.java
  23. 0 23
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/RedisLockFactoryAutoConfiguration.java
  24. 27 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/RedisLockManagerAutoConfiguration.java
  25. 2 1
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/resources/META-INF/spring.factories
  26. 80 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/LockAnnotationTest.java
  27. 40 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/LockService.java
  28. 12 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/TestApplication.java
  29. 12 0
      hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/resources/application.yml
  30. 1 1
      hsweb-core/src/main/java/org/hswebframework/web/id/IDGenerator.java
  31. 2 2
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/EntityProperties.java
  32. 2 2
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemVersion.java
  33. 1 1
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonHttpMessageConverter.java
  34. 1 1
      hsweb-starter/hsweb-spring-boot-starter/src/test/java/org/hswebframework/web/starter/InstallTests.java
  35. 6 1
      hsweb-system/hsweb-system-authorization/README.md
  36. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/AuthorizationSettingEntity.java
  37. 1 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/bind/BindPermissionRoleEntity.java
  38. 8 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingService.java
  39. 13 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java
  40. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleUserService.java
  41. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/java/org/hswebframework/web/authorization/starter/AuthorizationAutoConfigration.java
  42. 2 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js
  43. 0 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/AuthorizationSettingTests.java
  44. 1 1
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2RequestService.java
  45. 1 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AbstractScopeDataAccessHandler.java
  46. 1 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-service/hsweb-system-organizational-service-simple/src/main/java/org/hswebframework/web/service/organizational/simple/SimpleOrganizationalService.java

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/HttpTokenRequest.java

@@ -23,7 +23,7 @@ import org.hswebframework.web.authorization.oauth2.server.TokenRequest;
 import org.hswebframework.web.authorization.oauth2.server.exception.GrantTokenException;
 import org.hswebframework.web.oauth2.core.ErrorType;
 import org.hswebframework.web.oauth2.core.OAuth2Constants;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.*;

+ 1 - 1
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java

@@ -32,7 +32,7 @@ import org.hswebframework.web.authorization.annotation.Logical;
 import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 2 - 2
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/SimpleAuthorizeMethodInterceptor.java

@@ -33,8 +33,8 @@ import org.hswebframework.web.authorization.Role;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.annotation.Logical;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.hswebframwork.utils.ClassUtils;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.ClassUtils;
+import org.hswebframework.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java

@@ -14,7 +14,7 @@ import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.QueryController;
 import org.hswebframework.web.service.QueryService;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java

@@ -6,7 +6,7 @@ import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
 import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.authorization.access.*;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 
 /**
  * TODO 完成注释

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DatabaseType.java

@@ -19,7 +19,7 @@
 package org.hswebframework.web.dao.datasource;
 
 import org.hsweb.ezorm.rdb.render.dialect.Dialect;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 
 public enum DatabaseType {
     unknown(null, null, null, null),

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -42,7 +42,7 @@ import org.hswebframework.web.dao.datasource.DataSourceHolder;
 import org.hswebframework.web.dao.datasource.DatabaseType;
 import org.hswebframework.web.dao.mybatis.plgins.pager.Pager;
 import org.hswebframework.web.dao.mybatis.utils.ResultMapsUtils;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 
 import java.sql.JDBCType;
 import java.util.*;

+ 1 - 1
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupportEntity.java

@@ -20,7 +20,7 @@ package org.hswebframework.web.commons.entity;
 
 
 import org.hswebframework.web.id.IDGenerator;
-import org.hswebframwork.utils.RandomUtil;
+import org.hswebframework.utils.RandomUtil;
 
 import java.math.BigDecimal;
 import java.util.*;

+ 1 - 1
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/factory/MapperEntityFactory.java

@@ -20,7 +20,7 @@ package org.hswebframework.web.commons.entity.factory;
 
 import com.alibaba.fastjson.JSON;
 import org.hswebframework.web.NotFoundException;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 1 - 1
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java

@@ -5,7 +5,7 @@ import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.validate.SimpleValidateResults;
 import org.hswebframework.web.validate.ValidationException;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;

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

@@ -22,7 +22,7 @@ import org.hswebframework.web.commons.entity.GenericEntity;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.dao.CrudDao;
 import org.hswebframework.web.id.IDGenerator;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;

+ 9 - 9
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/AbstactLocakManager.java

@@ -10,30 +10,30 @@ import java.util.concurrent.locks.ReadWriteLock;
  *
  * @author zhouhao
  */
-public abstract class AbstactLocakManager implements LockManager {
+public abstract class AbstractLockManager implements LockManager {
     private final Map<String, Lock>          lockStore          = new HashMap<>(128);
     private final Map<String, ReadWriteLock> readWriteLockStore = new HashMap<>(128);
 
     @Override
-    public Lock getLock(String lockKey) {
-        Lock lock = lockStore.get(lockKey);
+    public Lock getLock(String lockName) {
+        Lock lock = lockStore.get(lockName);
         if (lock != null) return lock;
         synchronized (lockStore) {
-            return lockStore.computeIfAbsent(lockKey, this::createLock);
+            return lockStore.computeIfAbsent(lockName, this::createLock);
         }
     }
 
     @Override
-    public ReadWriteLock getReadWriteLock(String lockKey) {
-        ReadWriteLock lock = readWriteLockStore.get(lockKey);
+    public ReadWriteLock getReadWriteLock(String lockName) {
+        ReadWriteLock lock = readWriteLockStore.get(lockName);
         if (lock != null) return lock;
         synchronized (readWriteLockStore) {
-            return readWriteLockStore.computeIfAbsent(lockKey, this::createReadWriteLock);
+            return readWriteLockStore.computeIfAbsent(lockName, this::createReadWriteLock);
         }
     }
 
-    protected abstract Lock createLock(String lockKey);
+    protected abstract Lock createLock(String lockName);
 
-    protected abstract ReadWriteLock createReadWriteLock(String lockKey);
+    protected abstract ReadWriteLock createReadWriteLock(String lockName);
 
 }

+ 16 - 2
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/LockManager.java

@@ -12,7 +12,21 @@ import java.util.concurrent.locks.ReadWriteLock;
  * @since 3.0
  */
 public interface LockManager {
-    Lock getLock(String lockKey);
+    /**
+     * 根据锁名称获取锁,相同的名称,则锁也相同
+     *
+     * @param lockName 锁名称
+     * @return 锁对象
+     * @see Lock
+     */
+    Lock getLock(String lockName);
 
-    ReadWriteLock getReadWriteLock(String lockKey);
+    /**
+     * 根据锁名称获取读写锁,相同的名称,则锁也相同
+     *
+     * @param lockName 锁名称
+     * @return 读写锁对象
+     * @see ReadWriteLock
+     */
+    ReadWriteLock getReadWriteLock(String lockName);
 }

+ 4 - 4
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/SimpleLockManager.java

@@ -11,17 +11,17 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
  * @author zhouhao
  * @see ReentrantLock
  * @see ReentrantReadWriteLock
- * @see AbstactLocakManager
+ * @see AbstractLockManager
  * @since 3.0
  */
-public class SimpleLockManager extends AbstactLocakManager {
+public class SimpleLockManager extends AbstractLockManager {
     @Override
-    protected synchronized Lock createLock(String lockKey) {
+    protected Lock createLock(String lockName) {
         return new ReentrantLock();
     }
 
     @Override
-    protected synchronized ReadWriteLock createReadWriteLock(String lockKey) {
+    protected ReadWriteLock createReadWriteLock(String lockName) {
         return new ReentrantReadWriteLock();
     }
 }

+ 65 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/Lock.java

@@ -0,0 +1,65 @@
+package org.hswebframework.web.concurrent.lock.annotation;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 锁注解,在方法上注解,则对此方法加锁
+ *
+ * @author zhouhao
+ * @see org.hswebframework.web.concurrent.lock.LockManager
+ * @see java.util.concurrent.locks.Lock
+ * @since 3.0
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface Lock {
+    /**
+     * 锁名,支持表达式,表达式使用 ${} 进行标识;如果此值为空,则使用方法名称作为锁名
+     * e.g.
+     * <pre>
+     *     &#064;Lock("my_lock_${#id}")
+     *     public void foo(String id){
+     *
+     *     }
+     *
+     *     &#064;Lock(value="my_lock_${#id}",condition="#id!=null")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     *
+     * @return 锁名称, 支持spel表达式
+     * @see org.hswebframework.web.concurrent.lock.LockManager#getLock(String)
+     */
+    String[] value() default {};
+
+    /**
+     * 锁的条件表达式,当满足条件的时候才执行锁
+     * e.g.
+     * <pre>
+     *     &#064;Lock(value="my_lock_${#id}",condition="#id!=null")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     *
+     * @return 条件表达式
+     */
+    String condition() default "";
+
+
+    /**
+     * 超时时间,超过此时间不能获取锁则抛出异常{@link InterruptedException},如果设置为-1,则认为不设置超时时间
+     *
+     * @return 超时时间, 默认10秒
+     */
+    long timeout() default 10;
+
+    /**
+     * @return 超时时间单位, 秒
+     */
+    TimeUnit timeUnit() default TimeUnit.SECONDS;
+}

+ 64 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/ReadLock.java

@@ -0,0 +1,64 @@
+package org.hswebframework.web.concurrent.lock.annotation;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReadWriteLock;
+
+/**
+ * 读锁注解,在方法上注解,则对此方法加锁.
+ *
+ * @author zhouhao
+ * @see org.hswebframework.web.concurrent.lock.LockManager
+ * @see ReadWriteLock#readLock()
+ * @since 3.0
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface ReadLock {
+    /**
+     * 锁名,支持表达式,表达式使用 ${} 进行标识;如果此值为空,则使用方法名称作为锁名
+     * e.g.
+     * <pre>
+     *     &#064;ReadLock("my_lock_${#id}")
+     *     public void foo(String id){
+     *
+     *     }
+     *
+     *     &#064;ReadLock(value="my_lock_${#id}",condition="#id!=null")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     *
+     * @return 锁名称, 支持spel表达式
+     * @see org.hswebframework.web.concurrent.lock.LockManager#getReadWriteLock(String)
+     */
+    String[] value() default {};
+
+    /**
+     * 锁的条件表达式,当满足条件的时候才执行锁
+     * e.g.
+     * <pre>
+     *     &#064;ReadLock(value="my_lock_${#id}",condition="#id!=null")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     * @return 条件表达式
+     */
+    String condition() default "";
+
+    /**
+     * 超时时间,超过此时间不能获取锁则抛出异常{@link InterruptedException},如果设置为-1,则认为不设置超时时间
+     *
+     * @return 超时时间, 默认10秒
+     */
+    long timeout() default 10;
+
+    /**
+     * @return 超时时间单位, 秒
+     */
+    TimeUnit timeUnit() default TimeUnit.SECONDS;
+}

+ 60 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-api/src/main/java/org/hswebframework/web/concurrent/lock/annotation/WriteLock.java

@@ -0,0 +1,60 @@
+package org.hswebframework.web.concurrent.lock.annotation;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReadWriteLock;
+
+/**
+ * 写锁注解,在方法上注解,则对此方法加锁.
+ *
+ * @author zhouhao
+ * @see org.hswebframework.web.concurrent.lock.LockManager
+ * @see ReadWriteLock#writeLock()
+ * @since 3.0
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface WriteLock {
+    /**
+     * 锁名,支持表达式,表达式使用 ${} 进行标识;如果此值为空,则使用方法名称作为锁名
+     * e.g.
+     * <pre>
+     *     &#064;ReadLock("my_lock_${#id}")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     *
+     * @return 锁名称, 支持spel表达式
+     * @see org.hswebframework.web.concurrent.lock.LockManager#getReadWriteLock(String)
+     */
+    String[] value() default {};
+
+    /**
+     * 锁的条件表达式,当满足条件的时候才执行锁
+     * e.g.
+     * <pre>
+     *     &#064;WriteLock(value="my_lock_${#id}",condition="#id!=null")
+     *     public void foo(String id){
+     *
+     *     }
+     * </pre>
+     *
+     * @return 条件表达式
+     */
+    String condition() default "";
+
+    /**
+     * 超时时间,超过此时间不能获取锁则抛出异常{@link InterruptedException},如果设置为-1,则认为不设置超时时间
+     *
+     * @return 超时时间, 默认10秒
+     */
+    long timeout() default 10;
+
+    /**
+     * @return 超时时间单位, 秒
+     */
+    TimeUnit timeUnit() default TimeUnit.SECONDS;
+}

+ 9 - 10
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-redis/src/main/java/org/hswebframework/web/concurrent/lock/redis/RedissonLockManager.java

@@ -1,30 +1,29 @@
 package org.hswebframework.web.concurrent.lock.redis;
 
-import org.hswebframework.web.concurrent.lock.AbstactLocakManager;
-import org.redisson.Redisson;
+import org.hswebframework.web.concurrent.lock.AbstractLockManager;
+import org.redisson.api.RedissonClient;
 
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 
 /**
- *
  * @author zhouhao
  */
-public class RedissonLockManager extends AbstactLocakManager {
-    private Redisson redisson;
+public class RedissonLockManager extends AbstractLockManager {
+    private RedissonClient redisson;
 
-    public RedissonLockManager(Redisson redisson) {
+    public RedissonLockManager(RedissonClient redisson) {
         if (null == redisson) throw new NullPointerException();
         this.redisson = redisson;
     }
 
     @Override
-    protected Lock createLock(String lockKey) {
-        return redisson.getLock(lockKey);
+    protected Lock createLock(String lockName) {
+        return redisson.getLock(lockName);
     }
 
     @Override
-    protected ReadWriteLock createReadWriteLock(String lockKey) {
-        return redisson.getReadWriteLock(lockKey);
+    protected ReadWriteLock createReadWriteLock(String lockName) {
+        return redisson.getReadWriteLock(lockName);
     }
 }

+ 16 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/pom.xml

@@ -28,5 +28,21 @@
             <version>${project.version}</version>
             <optional>true</optional>
         </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-boost-aop</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-tests</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

+ 99 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/AopLockAdvisor.java

@@ -0,0 +1,99 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.hswebframework.web.AopUtils;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
+import org.hswebframework.web.concurrent.lock.LockManager;
+import org.hswebframework.web.concurrent.lock.annotation.Lock;
+import org.hswebframework.web.concurrent.lock.annotation.ReadLock;
+import org.hswebframework.web.concurrent.lock.annotation.WriteLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class AopLockAdvisor extends StaticMethodMatcherPointcutAdvisor {
+
+    public AopLockAdvisor(LockManager lockManager) {
+        Objects.requireNonNull(lockManager);
+        setAdvice((MethodInterceptor) methodInvocation -> {
+            MethodInterceptorHolder holder = MethodInterceptorHolder.create(methodInvocation);
+            Lock lockAnn = holder.findMethodAnnotation(Lock.class);
+            ReadLock readLockAnn = holder.findMethodAnnotation(ReadLock.class);
+            WriteLock writeLock = holder.findMethodAnnotation(WriteLock.class);
+            List<LockProcessor> lockProcessors = new ArrayList<>();
+            if (null != lockAnn) {
+                lockProcessors.add(initLockInfo(lockAnn.timeout(), lockAnn.timeUnit(),
+                        LockProcessor.<Lock, java.util.concurrent.locks.Lock>build(lockAnn, holder)
+                                .lockNameIs(Lock::value)
+                                .lockIs(lockManager::getLock)));
+            }
+            if (null != readLockAnn) {
+                lockProcessors.add(initLockInfo(readLockAnn.timeout(), readLockAnn.timeUnit(),
+                        LockProcessor.<ReadLock, java.util.concurrent.locks.Lock>build(readLockAnn, holder)
+                                .lockNameIs(ReadLock::value)
+                                .lockIs(name -> lockManager.getReadWriteLock(name).readLock())));
+            }
+            if (null != writeLock) {
+                lockProcessors.add(initLockInfo(writeLock.timeout(), writeLock.timeUnit(),
+                        LockProcessor.<WriteLock, java.util.concurrent.locks.Lock>build(writeLock, holder)
+                                .lockNameIs(WriteLock::value)
+                                .lockIs(name -> lockManager.getReadWriteLock(name).writeLock())));
+            }
+
+            try {
+                for (LockProcessor processor : lockProcessors) {
+                    Throwable e = processor.doLock();
+                    if (e != null) {
+                        throw e;
+                    }
+                }
+                return methodInvocation.proceed();
+            } finally {
+                for (LockProcessor processor : lockProcessors) {
+                    processor.doUnlock();
+                }
+            }
+        });
+    }
+
+    protected <A extends Annotation> LockProcessor<A, java.util.concurrent.locks.Lock> initLockInfo(long timeout, TimeUnit timeUnit, LockProcessor<A, java.util.concurrent.locks.Lock> lockProcessor) {
+        return lockProcessor.lock(lock -> {
+            try {
+                lock.tryLock(timeout, timeUnit);
+                return null;
+            } catch (InterruptedException e) {
+                return e;
+            }
+        }).unlock(lock -> {
+            try {
+                lock.unlock();
+                return null;
+            } catch (Throwable e) {
+                return e;
+            }
+        }).init();
+    }
+
+
+    @Override
+    public boolean matches(Method method, Class<?> aClass) {
+        Lock lock = AopUtils.findMethodAnnotation(aClass, method, Lock.class);
+        if (null != lock) return true;
+        ReadLock readLock = AopUtils.findMethodAnnotation(aClass, method, ReadLock.class);
+        if (null != readLock) return true;
+        WriteLock writeLock = AopUtils.findMethodAnnotation(aClass, method, WriteLock.class);
+        if (null != writeLock) return true;
+        return false;
+    }
+}

+ 8 - 3
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/LockFactoryAutoConfiguration.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.concurrent.lock.starter;
 
 import org.hswebframework.web.concurrent.lock.LockManager;
 import org.hswebframework.web.concurrent.lock.SimpleLockManager;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
@@ -13,12 +14,16 @@ import org.springframework.context.annotation.Configuration;
  * @author zhouhao
  */
 @Configuration
-@ImportAutoConfiguration(RedisLockFactoryAutoConfiguration.class)
-public class LockFactoryAutoConfiguration {
+public class LockManagerAutoConfiguration {
 
     @Bean
     @ConditionalOnMissingBean(LockManager.class)
-    public SimpleLockManager simpleLockFactory() {
+    public LockManager lockManager() {
         return new SimpleLockManager();
     }
+
+    @Bean
+    public AopLockAdvisor aopLockAdvisor(LockManager lockManager) {
+        return new AopLockAdvisor(lockManager);
+    }
 }

+ 120 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/LockProcessor.java

@@ -0,0 +1,120 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+
+import org.hswebframework.web.AopUtils;
+import org.hswebframework.web.ExpressionUtils;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+import java.lang.annotation.Annotation;
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@SuppressWarnings("unchecked")
+public class LockProcessor<A extends Annotation, L> {
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private A lockAnn;
+
+    private MethodInterceptorHolder interceptorHolder;
+
+    private Function<A, String[]> lockNameGetter;
+
+    private Function<String, L> lockGetter;
+
+    private Function<L, Throwable> lockAccepter;
+
+    private Function<L, Throwable> unlockAccepter;
+
+    private Map<String, L> lockStore = new HashMap<>();
+
+    private LockProcessor() {
+    }
+
+    public static <A extends Annotation, L> LockProcessor<A, L> build(A annotation, MethodInterceptorHolder holder) {
+        LockProcessor<A, L> alLockProcessor = new LockProcessor<>();
+        alLockProcessor.lockAnn = annotation;
+        alLockProcessor.interceptorHolder = holder;
+        return alLockProcessor;
+    }
+
+    public LockProcessor<A, L> lockNameIs(Function<A, String[]> lockNameGetter) {
+        this.lockNameGetter = lockNameGetter;
+        return this;
+    }
+
+    public LockProcessor<A, L> lockIs(Function<String, L> lockGetter) {
+        this.lockGetter = lockGetter;
+        return this;
+    }
+
+    public LockProcessor<A, L> lock(Function<L, Throwable> lockAccepter) {
+        this.lockAccepter = lockAccepter;
+        return this;
+    }
+
+    public LockProcessor<A, L> unlock(Function<L, Throwable> unlockAccepter) {
+        this.unlockAccepter = unlockAccepter;
+        return this;
+    }
+
+    public LockProcessor<A, L> init() {
+        Objects.requireNonNull(lockAnn);
+        Objects.requireNonNull(interceptorHolder);
+        Objects.requireNonNull(lockNameGetter);
+        String[] lockNameArr = lockNameGetter.apply(lockAnn);
+        if (lockNameArr.length == 0) {
+            String name = createLockName(null);
+            lockStore.put(name, lockGetter.apply(name));
+        } else {
+            for (String expression : lockNameArr) {
+                String name = createLockName(expression);
+                lockStore.put(name, lockGetter.apply(name));
+            }
+        }
+        return this;
+    }
+
+    protected String createLockName(String expression) {
+        try {
+            if (StringUtils.isEmpty(expression)) {
+                return interceptorHolder.getMethod().getName().concat("_").concat(interceptorHolder.getId());
+            }
+            return ExpressionUtils.analytical(expression, interceptorHolder.getArgs(), "spel");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private List<L> successLock = new ArrayList<>();
+
+    public Throwable doLock() {
+        Throwable lockError = null;
+        for (Map.Entry<String, L> lock : lockStore.entrySet()) {
+            Throwable error = lockAccepter.apply(lock.getValue());
+            if (error == null) {
+                successLock.add(lock.getValue());
+            } else {
+                lockError = error;
+            }
+        }
+        return lockError;
+    }
+
+    public void doUnlock() {
+        for (L lock : successLock) {
+            Throwable error = unlockAccepter.apply(lock);
+            if (null != error)
+                logger.error("unlock {} error", interceptorHolder.getMethod(), error);
+        }
+    }
+
+}

+ 0 - 23
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/RedisLockFactoryAutoConfiguration.java

@@ -1,23 +0,0 @@
-package org.hswebframework.web.concurrent.lock.starter;
-
-import org.hswebframework.web.concurrent.lock.redis.RedissonLockManager;
-import org.redisson.Redisson;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-@Configuration
-@ConditionalOnClass(Redisson.class)
-@ConditionalOnBean(Redisson.class)
-public class RedisLockFactoryAutoConfiguration {
-    @Bean
-    public RedissonLockManager redissonLockFactory(Redisson redisson) {
-        return new RedissonLockManager(redisson);
-    }
-}

+ 27 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/java/org/hswebframework/web/concurrent/lock/starter/RedisLockManagerAutoConfiguration.java

@@ -0,0 +1,27 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+import org.hswebframework.web.concurrent.lock.LockManager;
+import org.hswebframework.web.concurrent.lock.redis.RedissonLockManager;
+import org.redisson.api.RedissonClient;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Configuration
+@ConditionalOnClass(RedissonClient.class)
+@ConditionalOnBean(RedissonClient.class)
+//@AutoConfigureBefore(LockManagerAutoConfiguration.class)
+public class RedisLockManagerAutoConfiguration {
+    @Bean
+    public LockManager lockManager(RedissonClient redissonClient) {
+        return new RedissonLockManager(redissonClient);
+    }
+}

+ 2 - 1
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/main/resources/META-INF/spring.factories

@@ -1,3 +1,4 @@
 # Auto Configure
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.hswebframework.web.concurrent.lock.starter.LockFactoryAutoConfiguration
+org.hswebframework.web.concurrent.lock.starter.LockManagerAutoConfiguration,\
+  org.hswebframework.web.concurrent.lock.starter.RedisLockManagerAutoConfiguration

+ 80 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/LockAnnotationTest.java

@@ -0,0 +1,80 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+import org.hswebframework.web.concurrent.lock.LockManager;
+import org.hswebframework.web.tests.SimpleWebApplicationTests;
+import org.junit.Assert;
+import org.junit.Test;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Configuration
+public class LockAnnotationTest extends SimpleWebApplicationTests {
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private LockManager lockManager;
+
+    @Test
+    public void testLock() throws InterruptedException {
+        new Thread(() -> {
+            try {
+                System.out.println("锁住");
+                lockManager.getLock("lock_test").lock();
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            System.out.println("解锁");
+            lockManager.getLock("lock_test").unlock();
+        }).start();
+        Thread.sleep(200);
+        System.out.println("开始任务1");
+        lockService.testLock("test");
+        System.out.println("任务1结束");
+        for (int i = 0; i < 100; i++) {
+            new Thread(() -> lockService.testLock("test")).start();
+        }
+        Thread.sleep(5000);
+        Assert.assertEquals(lockService.getCounter(), 101);
+
+        lockService.reset();
+    }
+
+
+    @Test
+    public void testReadLock() throws InterruptedException {
+        new Thread(() -> {
+            try {
+                System.out.println("锁住");
+                lockManager.getReadWriteLock("lock_test").writeLock().lock();
+                Thread.sleep(2000); //停顿2秒
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            System.out.println("解锁");
+            lockManager.getReadWriteLock("lock_test").writeLock().unlock();
+        }).start();
+        Thread.sleep(200);
+        System.out.println("开始任务1");
+        lockService.testReadLock("test");
+        System.out.println("任务1结束");
+        for (int i = 0; i < 100; i++) {
+            new Thread(() -> lockService.testWriteLock("test")).start();
+        }
+        Thread.sleep(5000);
+        Assert.assertEquals(lockService.getCounter(), 101);
+        lockService.reset();
+    }
+
+
+}

+ 40 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/LockService.java

@@ -0,0 +1,40 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+import org.hswebframework.web.concurrent.lock.annotation.Lock;
+import org.hswebframework.web.concurrent.lock.annotation.ReadLock;
+import org.hswebframework.web.concurrent.lock.annotation.WriteLock;
+import org.springframework.stereotype.Service;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Service
+public class LockService {
+
+    private long counter = 0;
+
+    @Lock("lock_${#key}")
+    public long testLock(String key) {
+        return counter++;
+    }
+
+    @ReadLock("lock_${#key}")
+    public long testReadLock(String key) {
+        return counter++;
+    }
+
+    @WriteLock("lock_${#key}")
+    public long testWriteLock(String key) {
+        return counter++;
+    }
+
+    public long getCounter() {
+        return counter;
+    }
+
+    public void reset() {
+        counter = 0;
+    }
+}

+ 12 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/java/org/hswebframework/web/concurrent/lock/starter/TestApplication.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.concurrent.lock.starter;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class TestApplication {
+//    @Bean
+//    public RedissonClient redissonClient() {
+//        return Redisson.create();
+//    }
+
+}

+ 12 - 0
hsweb-concurrent/hsweb-concurrent-lock/hsweb-concurrent-lock-starter/src/test/resources/application.yml

@@ -0,0 +1,12 @@
+spring:
+    datasource:
+       url : jdbc:h2:mem:test_mem
+       username : sa
+       password :
+       type: com.alibaba.druid.pool.DruidDataSource
+       driver-class-name : org.h2.Driver
+
+hsweb:
+    app:
+      name: lock测试
+      version: 3.0.0

+ 1 - 1
hsweb-core/src/main/java/org/hswebframework/web/id/IDGenerator.java

@@ -18,7 +18,7 @@
 
 package org.hswebframework.web.id;
 
-import org.hswebframwork.utils.RandomUtil;
+import org.hswebframework.utils.RandomUtil;
 
 import java.math.BigInteger;
 import java.security.MessageDigest;

+ 2 - 2
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/EntityProperties.java

@@ -20,8 +20,8 @@ package org.hswebframework.web.starter;
 
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.MapperEntityFactory;
-import org.hswebframwork.utils.MapUtils;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.MapUtils;
+import org.hswebframework.utils.StringUtils;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.util.ClassUtils;
 

+ 2 - 2
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemVersion.java

@@ -20,8 +20,8 @@ package org.hswebframework.web.starter;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import org.hswebframwork.utils.ListUtils;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.ListUtils;
+import org.hswebframework.utils.StringUtils;
 
 import java.util.*;
 

+ 1 - 1
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonHttpMessageConverter.java

@@ -13,7 +13,7 @@ import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.commons.model.Model;
 import org.hswebframework.web.controller.message.ResponseMessage;
-import org.hswebframwork.utils.StringUtils;
+import org.hswebframework.utils.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
 import org.springframework.http.MediaType;

+ 1 - 1
hsweb-starter/hsweb-spring-boot-starter/src/test/java/org/hswebframework/web/starter/InstallTests.java

@@ -27,7 +27,7 @@ import org.hsweb.ezorm.rdb.simple.SimpleDatabase;
 import org.hswebframework.expands.script.engine.DynamicScriptEngine;
 import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
 import org.hswebframework.web.starter.init.simple.SimpleDependencyInstaller;
-import org.hswebframwork.utils.file.FileUtils;
+import org.hswebframework.utils.file.FileUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.LoggerFactory;

+ 6 - 1
hsweb-system/hsweb-system-authorization/README.md

@@ -4,4 +4,9 @@
 
 ## 授权
 [AuthorizationController](hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java)
-仅进行基础授权,通过触发`AuthorizationListener`,进行自定义控制逻辑.详细方式见:[hsweb-authorization-api](../../hsweb-authorization/hsweb-authorization-api#listener)
+仅进行基础授权,通过触发`AuthorizationListener`,进行自定义控制逻辑.详细方式见:[hsweb-authorization-api](../../hsweb-authorization/hsweb-authorization-api#listener)
+
+## 权限设置
+[AuthorizationSettingService]() 提供通用的权限设置,可在想要的地方进行设置,
+然后将用户支持的设置类型提供给[AuthorizationSettingTypeSupplier](),在初始化权限的时候,即可对相应的设置进行初始化.
+

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/AuthorizationSettingEntity.java

@@ -40,7 +40,7 @@ public interface AuthorizationSettingEntity extends GenericEntity<String> {
     /**
      * 状态
      */
-    String status      = "status";
+    String status     = "status";
     /**
      * 备注
      */

+ 1 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/bind/BindPermissionRoleEntity.java

@@ -10,6 +10,7 @@ import java.util.List;
  *
  * @author zhouhao
  */
+@Deprecated
 public interface BindPermissionRoleEntity<T extends PermissionRoleEntity> extends RoleEntity {
     List<T> getPermissions();
 

+ 8 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingService.java

@@ -20,10 +20,17 @@ import org.hswebframework.web.entity.authorization.AuthorizationSettingEntity;
 import org.hswebframework.web.service.CrudService;
 
 /**
- *  权限设置 服务类
+ * 权限设置 服务类,提供通用的权限设置
  *
  * @author hsweb-generator-online
  */
 public interface AuthorizationSettingService extends CrudService<AuthorizationSettingEntity, String> {
+    /**
+     * 根据类型和被设置者获取配置
+     *
+     * @param type       设置类型 {@link AuthorizationSettingEntity#getType()}
+     * @param settingFor {@link AuthorizationSettingEntity#getSettingFor()}
+     * @return 设置内容, 不存在时返回 <code>null</code>
+     */
     AuthorizationSettingEntity select(String type, String settingFor);
 }

+ 13 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java

@@ -16,7 +16,6 @@
  */
 package org.hswebframework.web.service.authorization.simple;
 
-import org.apache.commons.codec.digest.DigestUtils;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationInitializeService;
 import org.hswebframework.web.authorization.Permission;
@@ -89,14 +88,27 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
 
     @Override
     public AuthorizationSettingEntity select(String type, String settingFor) {
+        Objects.requireNonNull(type);
+        Objects.requireNonNull(settingFor);
         return createQuery().where(AuthorizationSettingEntity.type, type)
                 .and(AuthorizationSettingEntity.settingFor, settingFor)
                 .single();
     }
 
+    @Override
+    public String saveOrUpdate(AuthorizationSettingEntity entity) {
+        AuthorizationSettingEntity old = select(entity.getType(), entity.getSettingFor());
+        if (old != null) {
+            updateByPk(old.getId(), entity);
+            return old.getId();
+        }
+        return insert(entity);
+    }
+
     @Override
     @CacheEvict(allEntries = true)
     public String insert(AuthorizationSettingEntity entity) {
+        tryValidateProperty(select(entity.getType(), entity.getSettingFor()) == null, AuthorizationSettingEntity.settingFor, "存在相同的配置!");
         entity.setStatus(DataStatus.STATUS_ENABLED);
         String id = super.insert(entity);
         if (entity.getMenus() != null) {

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleUserService.java

@@ -16,7 +16,7 @@ import org.hswebframework.web.service.DefaultDSLQueryService;
 import org.hswebframework.web.service.DefaultDSLUpdateService;
 import org.hswebframework.web.service.authorization.*;
 import org.hswebframework.web.validate.ValidationException;
-import org.hswebframwork.utils.ListUtils;
+import org.hswebframework.utils.ListUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Caching;

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/java/org/hswebframework/web/authorization/starter/AuthorizationAutoConfigration.java

@@ -24,7 +24,7 @@ import org.hswebframework.web.authorization.listener.AuthorizationListener;
 import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
 import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
 import org.hswebframework.web.service.authorization.simple.SimpleAuthenticationManager;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

+ 2 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js

@@ -62,8 +62,8 @@ function install(context) {
         .addColumn().name("describe").varchar(128).comment("说明").commit()
         .addColumn().name("status").number(4).notNull().comment("状态").commit()
         .addColumn().name("actions").clob().notNull().comment("可选操作(按钮)").commit()
-        .addColumn().name("data_access").clob().notNull().comment("数据级控制配置").commit()
-        .addColumn().name("optional_fields").clob().notNull().comment("可选字段").commit()
+        .addColumn().name("data_access").clob().comment("数据级控制配置").commit()
+        .addColumn().name("optional_fields").clob().comment("可选字段").commit()
         .comment("权限表").commit();
 
     database.createOrAlter("s_permission_role")

+ 0 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/AuthorizationSettingTests.java

@@ -71,7 +71,6 @@ public class AuthorizationSettingTests extends SimpleWebApplicationTests {
         newEntity.setId("test");
 
         newEntity.setDescribe("测试2");
-
         result = testPut("/autz-setting/" + id)
                 .setUp(setup ->
                         setup.contentType(MediaType.APPLICATION_JSON)

+ 1 - 1
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2RequestService.java

@@ -30,7 +30,7 @@ import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
 import org.hswebframework.web.service.oauth2.client.OAuth2ServerConfigService;
 import org.hswebframework.web.service.oauth2.client.OAuth2UserTokenService;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 

+ 1 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AbstractScopeDataAccessHandler.java

@@ -14,7 +14,7 @@ import org.hswebframework.web.organizational.authorization.PersonnelAuthorizatio
 import org.hswebframework.web.organizational.authorization.access.DataAccessType;
 import org.hswebframework.web.organizational.authorization.entity.OrgAttachEntity;
 import org.hswebframework.web.service.QueryService;
-import org.hswebframwork.utils.ClassUtils;
+import org.hswebframework.utils.ClassUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 1 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-service/hsweb-system-organizational-service-simple/src/main/java/org/hswebframework/web/service/organizational/simple/SimpleOrganizationalService.java

@@ -23,7 +23,7 @@ import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.AbstractTreeSortService;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.organizational.OrganizationalService;
-import org.hswebframwork.utils.ListUtils;
+import org.hswebframework.utils.ListUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;