├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── festival-aop ├── build.gradle └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── bdqfork │ │ │ └── aop │ │ │ ├── MethodInvocation.java │ │ │ ├── MethodSignature.java │ │ │ ├── advice │ │ │ ├── AbstractAdvisor.java │ │ │ ├── AbstractAspectAdvice.java │ │ │ ├── Advice.java │ │ │ ├── Advisor.java │ │ │ ├── AfterAdvice.java │ │ │ ├── AfterReturningAdvice.java │ │ │ ├── AroundAdvice.java │ │ │ ├── AspectAdvice.java │ │ │ ├── AspectAdvisor.java │ │ │ ├── AspectAfterReturningAdvice.java │ │ │ ├── AspectAroundAdvice.java │ │ │ ├── AspectMethodBeforeAdvice.java │ │ │ ├── AspectThrowsAdvice.java │ │ │ ├── BeforeAdvice.java │ │ │ ├── MethodBeforeAdvice.java │ │ │ ├── RegexpMethodAdvisor.java │ │ │ └── ThrowsAdvice.java │ │ │ ├── factory │ │ │ ├── AopProxyBeanFactory.java │ │ │ └── DefaultAopProxyBeanFactory.java │ │ │ ├── processor │ │ │ ├── AopProxyProcessor.java │ │ │ └── AspectResolver.java │ │ │ └── proxy │ │ │ ├── AopProxy.java │ │ │ ├── AopProxyConfig.java │ │ │ ├── AopProxySupport.java │ │ │ ├── DefaultProxyInvocationHandler.java │ │ │ ├── ProxyInvocationHandler.java │ │ │ ├── cglib │ │ │ ├── CglibMethodInterceptor.java │ │ │ └── CglibProxy.java │ │ │ └── javassist │ │ │ ├── JavassistInvocationHandler.java │ │ │ └── JavassistProxy.java │ └── resources │ │ └── META-INF │ │ └── extensions │ │ └── cn.bdqfork.context.processor.LifeCycleProcessor │ └── test │ └── java │ └── cn │ └── bdqfork │ └── aop │ ├── MethodSignatureTest.java │ └── factory │ └── DefaultAopProxyBeanFactoryTest.java ├── festival-cache ├── build.gradle └── src │ └── main │ ├── java │ └── cn │ │ └── bdqfork │ │ └── cache │ │ ├── annotation │ │ ├── Cache.java │ │ └── Evict.java │ │ ├── constant │ │ ├── CacheProperty.kt │ │ └── RedisProperty.kt │ │ ├── processor │ │ └── CacheSupportProcessor.java │ │ ├── provider │ │ ├── AbstractCacheProvider.java │ │ ├── CacheProvider.java │ │ └── RedisCacheProvider.java │ │ └── proxy │ │ └── CacheInvocationHandler.java │ └── resources │ └── META-INF │ └── extensions │ └── cn.bdqfork.context.processor.LifeCycleProcessor ├── festival-context ├── build.gradle └── src │ ├── main │ └── java │ │ └── cn │ │ └── bdqfork │ │ └── context │ │ ├── AbstractApplicationContext.java │ │ ├── AnnotationApplicationContext.java │ │ ├── ApplicationContext.java │ │ ├── annotation │ │ └── ComponentScan.java │ │ ├── aware │ │ ├── BeanFactoryAware.java │ │ ├── ClassLoaderAware.java │ │ └── ResourceReaderAware.java │ │ ├── configuration │ │ ├── Configuration.java │ │ ├── Value.java │ │ └── reader │ │ │ ├── AbstractResourceReader.java │ │ │ ├── GenericResourceReader.java │ │ │ ├── PropertiesResourceReader.java │ │ │ ├── ResourceReader.java │ │ │ └── YamlResourceReader.java │ │ ├── factory │ │ ├── AbstractBeanDefinitionReader.java │ │ └── AnnotationBeanDefinitionReader.java │ │ └── processor │ │ ├── AbstractLifeCycleProcessor.java │ │ └── LifeCycleProcessor.java │ └── test │ ├── java │ └── cn │ │ └── bdqfork │ │ ├── context │ │ ├── AnnotationApplicationContextTest.java │ │ └── configuration │ │ │ └── reader │ │ │ └── GenericResourceReaderTest.java │ │ └── model │ │ ├── bean │ │ ├── SingletonBeanService.java │ │ ├── SingletonBeanServiceImpl.java │ │ ├── exception │ │ │ ├── ErrorBean.java │ │ │ ├── InjectedBean.java │ │ │ ├── ResolveExceptionBean.java │ │ │ └── unsatisfied │ │ │ │ ├── UnsatisfiedBeanExceptionBean.java │ │ │ │ └── WrongInjectedBean.java │ │ └── normal │ │ │ ├── SingletonBeanService.java │ │ │ └── SingletonBeanServiceImpl.java │ │ ├── collection │ │ ├── CollectionPropertyDao.java │ │ ├── CollectionPropertyDaoImpl1.java │ │ ├── CollectionPropertyDaoImpl2.java │ │ └── CollectionPropertyService.java │ │ ├── configuration │ │ ├── FactoryBean.java │ │ ├── FactoryMethodBean.java │ │ ├── Server.java │ │ └── ServerConfig.java │ │ ├── cycle │ │ ├── ConstructorCycleDao.java │ │ ├── ConstructorCycleDaoImpl.java │ │ ├── ConstructorCycleService.java │ │ ├── ConstructorCycleServiceImpl.java │ │ ├── FieldCycleDao.java │ │ ├── FieldCycleDaoImpl.java │ │ ├── FieldCycleService.java │ │ ├── FieldCycleServiceImpl.java │ │ ├── PrototypeConstructorCycleDao.java │ │ ├── PrototypeConstructorCycleDaoImpl.java │ │ ├── PrototypeConstructorCycleService.java │ │ ├── PrototypeConstructorCycleServiceImpl.java │ │ ├── PrototypeFieldCycleDao.java │ │ ├── PrototypeFieldCycleDaoImpl.java │ │ ├── PrototypeFieldCycleService.java │ │ ├── PrototypeFieldCycleServiceImpl.java │ │ ├── PrototypeSetterCycleDao.java │ │ ├── PrototypeSetterCycleDaoImpl.java │ │ ├── PrototypeSetterCycleService.java │ │ ├── PrototypeSetterCycleServiceImpl.java │ │ ├── ProviderCycleSetterDao.java │ │ ├── ProviderFieldCycleDao.java │ │ ├── ProviderFieldCycleDaoImpl.java │ │ ├── ProviderFieldCycleService.java │ │ ├── ProviderFieldCycleServiceImpl.java │ │ ├── ProviderSetterCycleDaoImpl.java │ │ ├── ProviderSetterCycleService.java │ │ ├── ProviderSetterCycleServiceImpl.java │ │ ├── SetterCycleDao.java │ │ ├── SetterCycleDaoImpl.java │ │ ├── SetterCycleService.java │ │ └── SetterCycleServiceImpl.java │ │ ├── jsr250 │ │ ├── JSR250FieldCycleDao.java │ │ ├── JSR250FieldCycleDaoImpl.java │ │ ├── JSR250FieldService.java │ │ ├── JSR250FieldServiceImpl.java │ │ ├── JSR250SetterCycleDao.java │ │ ├── JSR250SetterCycleDaoImpl.java │ │ ├── JSR250SetterCycleService.java │ │ └── JSR250SetterCycleServiceImpl.java │ │ ├── processor │ │ ├── MyOrder1processor.java │ │ ├── MyOrder2processor.java │ │ ├── MyOrderProcessor.java │ │ └── TestBean.java │ │ └── proxy │ │ ├── AopProxyTestBean.java │ │ ├── Log.java │ │ ├── OrderLog1.java │ │ └── OrderLog2.java │ └── resources │ ├── application-dev.yaml │ ├── application.yaml │ ├── logback.xml │ ├── testReadProperties.properties │ └── testReadYaml.yaml ├── festival-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── cn │ │ └── bdqfork │ │ └── core │ │ ├── annotation │ │ ├── Optimize.java │ │ └── Order.java │ │ ├── exception │ │ ├── BeansException.java │ │ ├── CircularDependencyException.java │ │ ├── ConflictedBeanException.java │ │ ├── FailedInjectedConstructorException.java │ │ ├── FailedInjectedFieldException.java │ │ ├── FailedInjectedMethodException.java │ │ ├── NoSuchBeanException.java │ │ ├── ResolvedException.java │ │ ├── ScopeException.java │ │ └── UnsatisfiedBeanException.java │ │ ├── extension │ │ ├── ExtensionLoader.java │ │ └── SPI.java │ │ ├── factory │ │ ├── AbstractAutoInjectedBeanFactory.java │ │ ├── AbstractBeanFactory.java │ │ ├── AbstractJSR250BeanFactory.java │ │ ├── AutoInjectedBeanfactory.java │ │ ├── BeanFactory.java │ │ ├── BeanNameGenerator.java │ │ ├── ConfigurableBeanFactory.java │ │ ├── DefaultBeanFactory.java │ │ ├── DefaultJSR250BeanFactory.java │ │ ├── DisposableBean.java │ │ ├── InitializingBean.java │ │ ├── InjectedPoint.java │ │ ├── JSR250BeanFactory.java │ │ ├── MultInjectedPoint.java │ │ ├── SimpleBeanNameGenerator.java │ │ ├── definition │ │ │ ├── BeanDefinition.java │ │ │ └── ManagedBeanDefinition.java │ │ ├── processor │ │ │ ├── BeanFactoryPostProcessor.java │ │ │ ├── BeanPostProcessor.java │ │ │ └── OrderAware.java │ │ └── registry │ │ │ ├── BeanDefinitionRegistry.java │ │ │ ├── DefaultSingletonBeanRegistry.java │ │ │ ├── Registry.java │ │ │ └── SingletonBeanRegistry.java │ │ ├── proxy │ │ ├── FestivalProxy.java │ │ ├── TargetClassAware.java │ │ └── javassist │ │ │ ├── ClassGenerator.java │ │ │ └── Proxy.java │ │ └── util │ │ ├── AnnotationUtils.java │ │ ├── AopUtils.java │ │ ├── BeanUtils.java │ │ ├── FileUtils.java │ │ ├── ReflectUtils.java │ │ └── StringUtils.java │ └── test │ ├── java │ └── cn │ │ └── bdqfork │ │ ├── core │ │ ├── extension │ │ │ ├── ExtensionLoaderTest.java │ │ │ ├── ExtensionTestImpl1.java │ │ │ ├── ExtensionTestImpl2.java │ │ │ └── IExtensionTest.java │ │ ├── factory │ │ │ └── support │ │ │ │ └── DefaultBeanFactoryTest.java │ │ └── util │ │ │ ├── AnnotationUtilsTest.java │ │ │ └── ReflectUtilsTest.java │ │ └── model │ │ └── bean │ │ ├── SingletonBeanService.java │ │ └── SingletonBeanServiceImpl.java │ └── resources │ ├── META-INF │ └── extensions │ │ └── cn.bdqfork.core.extension.IExtensionTest │ └── logback.xml ├── festival-example ├── build.gradle ├── kotlin-web │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── bdqfork │ │ │ └── kotlin │ │ │ └── example │ │ │ ├── Hello.java │ │ │ ├── config │ │ │ ├── AuthConfig.java │ │ │ └── ServerConfig.java │ │ │ ├── domain │ │ │ ├── IService.java │ │ │ ├── ServiceImpl.java │ │ │ ├── ServiceImpl2.java │ │ │ ├── TestRestfulController.java │ │ │ ├── UserController.java │ │ │ └── WebSocketTestController.java │ │ │ └── model │ │ │ └── User.java │ │ └── resources │ │ ├── application.yaml │ │ ├── logback.xml │ │ ├── static │ │ └── index.html │ │ ├── template │ │ └── index.html │ │ ├── test.jks │ │ └── vertx-users.properties └── web │ ├── build.gradle │ └── src │ └── main │ ├── java │ └── cn │ │ └── bdqfork │ │ └── kotlin │ │ └── example │ │ ├── Hello.java │ │ ├── config │ │ ├── AuthConfig.java │ │ └── ServerConfig.java │ │ ├── domain │ │ ├── IService.java │ │ ├── ServiceImpl.java │ │ ├── ServiceImpl2.java │ │ ├── TestRestfulController.java │ │ ├── UserController.java │ │ └── WebSocketTestController.java │ │ └── model │ │ └── User.java │ └── resources │ ├── application.yaml │ ├── logback.xml │ ├── static │ └── index.html │ ├── template │ ├── freemarker.ftl │ ├── jade.jade │ └── thymeleaf.html │ ├── test.jks │ └── vertx-users.properties ├── festival-kotlin-web ├── build.gradle └── src │ └── main │ ├── kotlin │ └── cn │ │ └── bdqfork │ │ └── kotlin │ │ └── web │ │ ├── RouterAware.kt │ │ ├── VertxAware.kt │ │ ├── WebApplication.kt │ │ ├── WebApplicationContext.kt │ │ ├── annotation │ │ ├── Auth.kt │ │ ├── PermitAll.kt │ │ ├── PermitAllowed.kt │ │ ├── RolesAllowed.kt │ │ └── VerticleMapping.kt │ │ ├── constant │ │ ├── ContentType.kt │ │ ├── LogicType.kt │ │ └── ServerProperty.kt │ │ ├── processor │ │ ├── VerticleProxyProcessor.kt │ │ └── WebLifeCycleProcessor.kt │ │ ├── route │ │ ├── ModelAndView.kt │ │ ├── PermitHolder.kt │ │ ├── RouteAttribute.kt │ │ ├── RouteHandler.kt │ │ ├── RouteManager.kt │ │ ├── RouteResolver.kt │ │ ├── SessionManager.kt │ │ ├── TemplateManager.kt │ │ ├── annotation │ │ │ ├── Consumes.kt │ │ │ ├── DeleteMapping.kt │ │ │ ├── GetMapping.kt │ │ │ ├── OnActive.kt │ │ │ ├── OnClose.kt │ │ │ ├── OnOpen.kt │ │ │ ├── Param.kt │ │ │ ├── PostMapping.kt │ │ │ ├── Produces.kt │ │ │ ├── PutMapping.kt │ │ │ ├── RequestBody.kt │ │ │ ├── RouteController.kt │ │ │ ├── RouteMapping.kt │ │ │ └── ServerEndpoint.kt │ │ ├── filter │ │ │ ├── AuthFilter.kt │ │ │ ├── Filter.kt │ │ │ ├── FilterChain.kt │ │ │ └── FilterChainFactory.kt │ │ ├── message │ │ │ ├── AbstractHttpMessageHandler.kt │ │ │ ├── DefaultHttpMessageHandler.kt │ │ │ ├── HttpMessageHandler.kt │ │ │ └── resolver │ │ │ │ ├── AbstractParameterResolver.kt │ │ │ │ ├── ContextParameterResolver.kt │ │ │ │ ├── DateParameterResolver.kt │ │ │ │ ├── JsonBodyParameterResolver.kt │ │ │ │ ├── ParameterResolver.kt │ │ │ │ ├── ParameterResolverFactory.kt │ │ │ │ ├── PrimitiveParameterResolver.kt │ │ │ │ └── XmlBodyParameterResolver.kt │ │ └── response │ │ │ ├── AbstractResponseHandler.kt │ │ │ ├── HtmlResponseHandler.kt │ │ │ ├── JsonResponseHandler.kt │ │ │ ├── ResponseHandleStrategy.kt │ │ │ ├── ResponseHandlerFactory.kt │ │ │ ├── TextPlainResponseHandler.kt │ │ │ └── XmlResponseHandler.kt │ │ ├── server │ │ ├── DefaultWebServer.kt │ │ ├── WebServer.kt │ │ ├── WebSocketRouter.kt │ │ └── WebVerticle.kt │ │ ├── service │ │ ├── JsonMessageCodec.kt │ │ ├── MethodInvocation.kt │ │ ├── ServiceVerticle.kt │ │ └── VerticleProxyHandler.kt │ │ └── util │ │ ├── EventBusUtils.kt │ │ ├── SecurityUtils.kt │ │ ├── VertxUtils.kt │ │ └── XmlUtils.kt │ └── resources │ └── META-INF │ └── extensions │ └── cn.bdqfork.context.processor.LifeCycleProcessor ├── festival-web ├── build.gradle └── src │ └── main │ ├── java │ └── cn │ │ └── bdqfork │ │ └── web │ │ ├── RouterAware.java │ │ ├── VertxAware.java │ │ ├── WebApplication.java │ │ ├── WebApplicationContext.java │ │ ├── annotation │ │ ├── Auth.java │ │ ├── PermitAll.java │ │ ├── PermitAllowed.java │ │ ├── RolesAllowed.java │ │ └── VerticleMapping.java │ │ ├── constant │ │ ├── ContentType.java │ │ ├── LogicType.java │ │ └── ServerProperty.java │ │ ├── processor │ │ ├── VerticleProxyProcessor.java │ │ └── WebLifeCycleProcessor.java │ │ ├── route │ │ ├── ModelAndView.java │ │ ├── PermitHolder.java │ │ ├── RouteAttribute.java │ │ ├── RouteHandler.java │ │ ├── RouteManager.java │ │ ├── RouteResolver.java │ │ ├── SessionManager.java │ │ ├── TemplateManager.java │ │ ├── annotation │ │ │ ├── Consumes.java │ │ │ ├── DeleteMapping.java │ │ │ ├── GetMapping.java │ │ │ ├── OnActive.java │ │ │ ├── OnClose.java │ │ │ ├── OnOpen.java │ │ │ ├── Param.java │ │ │ ├── PostMapping.java │ │ │ ├── Produces.java │ │ │ ├── PutMapping.java │ │ │ ├── RequestBody.java │ │ │ ├── RouteController.java │ │ │ ├── RouteMapping.java │ │ │ └── ServerEndpoint.java │ │ ├── filter │ │ │ ├── AuthFilter.java │ │ │ ├── Filter.java │ │ │ ├── FilterChain.java │ │ │ └── FilterChainFactory.java │ │ ├── message │ │ │ ├── AbstractHttpMessageHandler.java │ │ │ ├── DefaultHttpMessageHandler.java │ │ │ ├── HttpMessageHandler.java │ │ │ └── resolver │ │ │ │ ├── AbstractParameterResolver.java │ │ │ │ ├── ContextParameterResolver.java │ │ │ │ ├── DateParameterResolver.java │ │ │ │ ├── JsonBodyParameterResolver.java │ │ │ │ ├── ParameterResolver.java │ │ │ │ ├── ParameterResolverFactory.java │ │ │ │ ├── PrimitiveParameterResolver.java │ │ │ │ └── XmlBodyParameterResolver.java │ │ └── response │ │ │ ├── AbstractResponseHandler.java │ │ │ ├── HtmlResponseHandler.java │ │ │ ├── JsonResponseHandler.java │ │ │ ├── ResponseHandleStrategy.java │ │ │ ├── ResponseHandlerFactory.java │ │ │ ├── TextPlainResponseHandler.java │ │ │ └── XmlResponseHandler.java │ │ ├── server │ │ ├── AbstractWebServer.java │ │ ├── DefaultWebServer.java │ │ ├── WebServer.java │ │ ├── WebSocketRouter.java │ │ └── WebVerticle.java │ │ ├── service │ │ ├── JsonMessageCodec.java │ │ ├── MethodInvocation.java │ │ ├── ServiceVerticle.java │ │ └── VerticleProxyHandler.java │ │ └── util │ │ ├── EventBusUtils.java │ │ ├── SecurityUtils.java │ │ ├── VertxUtils.java │ │ └── XmlUtils.java │ └── resources │ └── META-INF │ └── extensions │ └── cn.bdqfork.context.processor.LifeCycleProcessor ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── images ├── aop-design.png ├── design.png └── mvc-design.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | .DS_Store 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | .vscode 27 | file-uploads/ 28 | .gradle 29 | build/ 30 | out/ 31 | gradle.properties 32 | -------------------------------------------------------------------------------- /festival-aop/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | implementation "cglib:cglib:${libs.cglib}" 5 | implementation "org.objenesis:objenesis:${libs.objenesis}" 6 | api "org.aspectj:aspectjweaver:${libs.aspectjweaver}" 7 | implementation project(':festival-context') 8 | } 9 | 10 | publishing { 11 | publications { 12 | mavenJava(MavenPublication) { 13 | pom { 14 | description = 'Aop extension for festival context!' 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/MethodSignature.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop; 2 | 3 | import cn.bdqfork.core.util.ReflectUtils; 4 | import org.aspectj.lang.Signature; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2019/12/23 11 | */ 12 | public class MethodSignature implements Signature { 13 | /** 14 | * 方法所属类 15 | */ 16 | private Class targetClass; 17 | /** 18 | * 方法 19 | */ 20 | private Method method; 21 | 22 | public MethodSignature(Method method) { 23 | this.method = method; 24 | this.targetClass = method.getDeclaringClass(); 25 | } 26 | 27 | @Override 28 | public String toShortString() { 29 | return ReflectUtils.getSignature(method); 30 | } 31 | 32 | @Override 33 | public String toLongString() { 34 | return targetClass.getTypeName() + "." + toShortString(); 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return method.getName(); 40 | } 41 | 42 | @Override 43 | public int getModifiers() { 44 | return method.getModifiers(); 45 | } 46 | 47 | @Override 48 | public Class getDeclaringType() { 49 | return targetClass; 50 | } 51 | 52 | @Override 53 | public String getDeclaringTypeName() { 54 | return getDeclaringType().getTypeName(); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return toLongString(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/Advice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/23 6 | */ 7 | public interface Advice { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/Advisor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface Advisor extends Advice { 10 | /** 11 | * 设置切点 12 | * 13 | * @param pointcut 切点表达式 14 | */ 15 | void setPointcut(String pointcut); 16 | 17 | /** 18 | * 获取切点表达式 19 | * 20 | * @return String 21 | */ 22 | String getPointcut(); 23 | 24 | /** 25 | * 设置通知 26 | * 27 | * @param advice 通知 28 | */ 29 | void setAdvice(Advice advice); 30 | 31 | /** 32 | * 获取通知 33 | * 34 | * @return Advice 35 | */ 36 | Advice getAdvice(); 37 | 38 | /** 39 | * 代理方法是否匹配通知 40 | * 41 | * @param method 代理方法 42 | * @param adviceType 通知类型 43 | * @return boolean 44 | */ 45 | boolean isMatch(Method method, Class adviceType); 46 | 47 | boolean isAdviceTypeOf(Class adviceType); 48 | } 49 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AfterAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/23 6 | */ 7 | public interface AfterAdvice extends Advice { 8 | } 9 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AfterReturningAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface AfterReturningAdvice extends AfterAdvice { 10 | /** 11 | * 执行后置通知 12 | * 13 | * @param returnValue 代理方法返回值 14 | * @param method 代理方法 15 | * @param args 代理方法参数 16 | * @param target 代理目标类 17 | * @throws Throwable 异常 18 | */ 19 | void afterReturning(Object returnValue, Method method, Object[] args, 20 | Object target) throws Throwable; 21 | } 22 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AroundAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import cn.bdqfork.aop.MethodInvocation; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface AroundAdvice extends Advice { 10 | /** 11 | * 执行环绕通知 12 | * 13 | * @param invocation 切点 14 | * @return Object 方法执行结果 15 | * @throws Throwable 异常 16 | */ 17 | Object invoke(MethodInvocation invocation) throws Throwable; 18 | } 19 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public interface AspectAdvice extends Advice { 12 | /** 13 | * 注入切点实例 14 | * 15 | * @param joinPoint 切点 16 | */ 17 | void setJoinPoint(JoinPoint joinPoint); 18 | 19 | /** 20 | * 注入切面类实例 21 | * 22 | * @param aspectInstance 切面实例 23 | */ 24 | void setAspectInstance(Object aspectInstance); 25 | 26 | /** 27 | * 获取切面类实例 28 | * 29 | * @return Object 切面实例 30 | */ 31 | Object getAspectInstance(); 32 | 33 | /** 34 | * 注入切面通知方法 35 | * 36 | * @param aspectAdviceMethod 切面方法 37 | */ 38 | void setAspectAdviceMethod(Method aspectAdviceMethod); 39 | } 40 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectAdvisor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import cn.bdqfork.aop.MethodSignature; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class AspectAdvisor extends AbstractAdvisor { 12 | 13 | @Override 14 | public boolean isMatch(Method method, Class adviceType) { 15 | AspectAdvice aspectAdvice = (AspectAdvice) getAdvice(); 16 | 17 | MethodSignature methodSignature = new MethodSignature(method); 18 | String fullyMethodName = methodSignature.toLongString(); 19 | 20 | return adviceType.isAssignableFrom(aspectAdvice.getClass()) && fullyMethodName.matches(getPointcut()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectAfterReturningAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class AspectAfterReturningAdvice extends AbstractAspectAdvice implements AfterReturningAdvice { 12 | 13 | @Override 14 | public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { 15 | Object[] adviceArgs = getAdviceArgs(returnValue, JoinPoint.class); 16 | //执行切面通知方法 17 | aspectAdviceMethod.invoke(aspectInstance, adviceArgs); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectAroundAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | 4 | import cn.bdqfork.aop.MethodInvocation; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class AspectAroundAdvice extends AbstractAspectAdvice implements AroundAdvice { 12 | 13 | @Override 14 | public Object invoke(MethodInvocation invocation) throws Throwable { 15 | if (invocation != null) { 16 | joinPoint = invocation; 17 | } 18 | Object[] adviceArgs = getAdviceArgs(null, ProceedingJoinPoint.class); 19 | //执行切面通知方法 20 | return aspectAdviceMethod.invoke(aspectInstance, adviceArgs); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectMethodBeforeAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class AspectMethodBeforeAdvice extends AbstractAspectAdvice implements MethodBeforeAdvice { 12 | 13 | @Override 14 | public void before(Method method, Object[] args, Object target) throws Throwable { 15 | Object[] adviceArgs = getAdviceArgs(null, JoinPoint.class); 16 | //执行切面通知方法 17 | aspectAdviceMethod.invoke(aspectInstance, adviceArgs); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/AspectThrowsAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2019/12/23 11 | */ 12 | public class AspectThrowsAdvice extends AbstractAspectAdvice implements ThrowsAdvice { 13 | 14 | @Override 15 | public void afterThrowing(Method method, Object[] args, Object target, Exception ex) { 16 | Object[] adviceArgs = getAdviceArgs(ex, JoinPoint.class); 17 | try { 18 | //执行切面通知方法 19 | aspectAdviceMethod.invoke(aspectInstance, adviceArgs); 20 | } catch (IllegalAccessException | InvocationTargetException e) { 21 | //如果切面通知方法有异常,则抛出 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/BeforeAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/23 6 | */ 7 | public interface BeforeAdvice extends Advice { 8 | } 9 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/MethodBeforeAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface MethodBeforeAdvice extends BeforeAdvice { 10 | /** 11 | * 执行前置通知 12 | * 13 | * @param method 代理方法 14 | * @param args 代理方法参数 15 | * @param target 代理目标类 16 | * @throws Throwable 异常 17 | */ 18 | void before(Method method, Object[] args, Object target) throws Throwable; 19 | } 20 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/RegexpMethodAdvisor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import cn.bdqfork.aop.MethodSignature; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class RegexpMethodAdvisor extends AbstractAdvisor { 12 | 13 | @Override 14 | public boolean isMatch(Method method, Class adviceType) { 15 | MethodSignature methodSignature = new MethodSignature(method); 16 | String fullyMethodName = methodSignature.toLongString(); 17 | return adviceType.isAssignableFrom(getAdvice().getClass()) && fullyMethodName.matches(getPointcut()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/advice/ThrowsAdvice.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.advice; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface ThrowsAdvice extends Advice { 10 | /** 11 | * 执行异常通知,如果执行过程中出异常,会抛出runtime异常 12 | * 13 | * @param method 代理方法 14 | * @param args 代理方法参数 15 | * @param target 代理目标类 16 | * @param ex 异常实例 17 | */ 18 | void afterThrowing(Method method, Object[] args, Object target, Exception ex); 19 | } 20 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/factory/AopProxyBeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.factory; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxySupport; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/27 8 | */ 9 | public interface AopProxyBeanFactory { 10 | 11 | Object createAopProxyBean(AopProxySupport config); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/factory/DefaultAopProxyBeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.factory; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxySupport; 4 | import cn.bdqfork.aop.proxy.cglib.CglibProxy; 5 | import cn.bdqfork.aop.proxy.javassist.JavassistProxy; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/23 10 | */ 11 | public class DefaultAopProxyBeanFactory implements AopProxyBeanFactory { 12 | 13 | @Override 14 | public Object createAopProxyBean(AopProxySupport config) { 15 | if (config.getBeanClass().isInterface() || (!config.isOptimze() && config.getInterfaces() != null && config.getInterfaces().size() > 0)) { 16 | return new JavassistProxy(config).getProxy(); 17 | } 18 | return new CglibProxy(config).getProxy(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/AopProxy.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/14 6 | */ 7 | public interface AopProxy { 8 | 9 | Object getProxy(); 10 | 11 | Object getProxy(ClassLoader classLoader); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/AopProxyConfig.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/14 8 | */ 9 | public class AopProxyConfig { 10 | 11 | private Class beanClass; 12 | 13 | private Object bean; 14 | 15 | private List> interfaces; 16 | 17 | private boolean optimze; 18 | 19 | public Class getBeanClass() { 20 | return beanClass; 21 | } 22 | 23 | public void setBeanClass(Class beanClass) { 24 | this.beanClass = beanClass; 25 | } 26 | 27 | public Object getBean() { 28 | return bean; 29 | } 30 | 31 | public void setBean(Object bean) { 32 | this.bean = bean; 33 | } 34 | 35 | public List> getInterfaces() { 36 | return interfaces; 37 | } 38 | 39 | public void setInterfaces(List> interfaces) { 40 | this.interfaces = interfaces; 41 | } 42 | 43 | public boolean isOptimze() { 44 | return optimze; 45 | } 46 | 47 | public void setOptimze(boolean optimze) { 48 | this.optimze = optimze; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/ProxyInvocationHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019/12/23 8 | */ 9 | public interface ProxyInvocationHandler { 10 | 11 | Object invoke(Method method, Object[] args) throws Throwable; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/cglib/CglibMethodInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy.cglib; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxySupport; 4 | import cn.bdqfork.aop.proxy.DefaultProxyInvocationHandler; 5 | import net.sf.cglib.proxy.MethodInterceptor; 6 | import net.sf.cglib.proxy.MethodProxy; 7 | 8 | import java.lang.reflect.Method; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2019/12/23 13 | */ 14 | public class CglibMethodInterceptor extends DefaultProxyInvocationHandler implements MethodInterceptor { 15 | 16 | public CglibMethodInterceptor(AopProxySupport support) { 17 | super(support); 18 | } 19 | 20 | @Override 21 | public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 22 | return invoke(method, args); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/javassist/JavassistInvocationHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy.javassist; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxySupport; 4 | import cn.bdqfork.aop.proxy.DefaultProxyInvocationHandler; 5 | 6 | import java.lang.reflect.InvocationHandler; 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2019/12/23 12 | */ 13 | public class JavassistInvocationHandler extends DefaultProxyInvocationHandler implements InvocationHandler { 14 | 15 | public JavassistInvocationHandler(AopProxySupport support) { 16 | super(support); 17 | } 18 | 19 | @Override 20 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 21 | return invoke(method, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /festival-aop/src/main/java/cn/bdqfork/aop/proxy/javassist/JavassistProxy.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.proxy.javassist; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxy; 4 | import cn.bdqfork.aop.proxy.AopProxySupport; 5 | import cn.bdqfork.core.proxy.FestivalProxy; 6 | import cn.bdqfork.core.proxy.TargetClassAware; 7 | import cn.bdqfork.core.proxy.javassist.Proxy; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author bdq 13 | * @since 2020/1/14 14 | */ 15 | public class JavassistProxy implements AopProxy { 16 | private AopProxySupport support; 17 | 18 | public JavassistProxy(AopProxySupport support) { 19 | this.support = support; 20 | } 21 | 22 | @Override 23 | public Object getProxy() { 24 | return getProxy(null); 25 | } 26 | 27 | @Override 28 | public Object getProxy(ClassLoader classLoader) { 29 | Class targetClass = support.getBeanClass(); 30 | if (classLoader == null) { 31 | classLoader = targetClass.getClassLoader(); 32 | } 33 | List> interfaces = support.getInterfaces(); 34 | interfaces.add(FestivalProxy.class); 35 | interfaces.add(TargetClassAware.class); 36 | if (targetClass.isInterface()) { 37 | interfaces.add(targetClass); 38 | } 39 | return Proxy.newProxyInstance(classLoader, interfaces.toArray(new Class[0]), new JavassistInvocationHandler(support)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /festival-aop/src/main/resources/META-INF/extensions/cn.bdqfork.context.processor.LifeCycleProcessor: -------------------------------------------------------------------------------- 1 | aop=cn.bdqfork.aop.processor.AopProxyProcessor -------------------------------------------------------------------------------- /festival-aop/src/test/java/cn/bdqfork/aop/MethodSignatureTest.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop; 2 | 3 | import cn.bdqfork.core.util.ReflectUtils; 4 | import org.junit.Test; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | import static org.junit.Assert.*; 9 | 10 | public class MethodSignatureTest { 11 | 12 | @Test 13 | public void toShortString() throws NoSuchMethodException { 14 | Method method = Foo.class.getMethod("foo", String.class); 15 | MethodSignature methodSignature = new MethodSignature(method); 16 | System.out.println(methodSignature.toShortString()); 17 | System.out.println(ReflectUtils.getSignature(method)); 18 | } 19 | 20 | static class Foo { 21 | public void foo(String s) { 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /festival-aop/src/test/java/cn/bdqfork/aop/factory/DefaultAopProxyBeanFactoryTest.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.aop.factory; 2 | 3 | import cn.bdqfork.aop.proxy.AopProxySupport; 4 | import cn.bdqfork.core.proxy.TargetClassAware; 5 | import cn.bdqfork.core.util.AopUtils; 6 | import org.junit.Test; 7 | 8 | import javax.inject.Named; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class DefaultAopProxyBeanFactoryTest { 14 | 15 | @Test 16 | public void createAopProxyBean() { 17 | AopProxyBeanFactory aopProxyBeanFactory = new DefaultAopProxyBeanFactory(); 18 | AopProxySupport support = new AopProxySupport(); 19 | ProxyInterface proxyBean = new ProxyBean(); 20 | support.setBean(proxyBean); 21 | support.setBeanClass(ProxyBean.class); 22 | 23 | List> interfaces = new ArrayList<>(); 24 | interfaces.add(ProxyInterface.class); 25 | support.setInterfaces(interfaces); 26 | 27 | proxyBean = (ProxyInterface) aopProxyBeanFactory.createAopProxyBean(support); 28 | assert proxyBean instanceof TargetClassAware; 29 | 30 | TargetClassAware targetClassAware = (TargetClassAware) proxyBean; 31 | assert targetClassAware.getTargetClass().isAnnotationPresent(Named.class); 32 | 33 | assert AopUtils.isProxy(proxyBean); 34 | } 35 | 36 | public interface ProxyInterface { 37 | 38 | } 39 | 40 | @Named 41 | static class ProxyBean implements ProxyInterface { 42 | 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /festival-cache/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | implementation "io.vertx:vertx-redis-client:${libs.vertx}" 5 | implementation "io.vertx:vertx-lang-kotlin-coroutines:${libs.vertx}" 6 | implementation project(':festival-context') 7 | } 8 | 9 | tasks.withType(PublishToMavenRepository) { 10 | onlyIf { 11 | false 12 | } 13 | } 14 | tasks.withType(PublishToMavenLocal) { 15 | onlyIf { 16 | false 17 | } 18 | } 19 | 20 | publishing { 21 | publications { 22 | mavenJava(MavenPublication) { 23 | pom { 24 | description = 'Cache extension for festival context!' 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/annotation/Cache.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 该注解使用在方法上,在方法执行完之后,对方法的结果进行缓存,再次执行操作时,若缓存不为空,则直接返回缓存结果。 7 | * 8 | * @author bdq 9 | * @since 2020/2/17 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.METHOD) 14 | public @interface Cache { 15 | /** 16 | * 缓存的key 17 | */ 18 | String value(); 19 | 20 | /** 21 | * 缓存过期时间,单位秒,默认60秒 22 | */ 23 | long expireTime() default 60; 24 | } 25 | -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/annotation/Evict.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 该注解使用在方法上,在方法执行完之后,删除指定的缓存 7 | * 8 | * @author bdq 9 | * @since 2020/2/17 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.METHOD) 14 | public @interface Evict { 15 | /** 16 | * 缓存的key 17 | */ 18 | String value(); 19 | } 20 | -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/constant/CacheProperty.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.constant 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/17 6 | */ 7 | object CacheProperty { 8 | const val REDIS_CACHE_TYPE = "redis" 9 | 10 | const val DEFAULT_EXPIRE_TIME: Long = 60 11 | const val DEFAULT_CACHE_TYPE = REDIS_CACHE_TYPE 12 | 13 | 14 | const val CACHE_ENABLE = "cache.enable" 15 | const val CACHE_TYPE = "cache.type" 16 | } -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/constant/RedisProperty.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.constant 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/17 6 | */ 7 | object RedisProperty { 8 | const val REDIS_HOST = "redis.host" 9 | const val REDIS_USERNAME = "redis.username" 10 | const val REDIS_PASSWORD = "redis.password" 11 | } -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/provider/AbstractCacheProvider.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.provider; 2 | 3 | import cn.bdqfork.cache.constant.CacheProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/21 10 | */ 11 | public abstract class AbstractCacheProvider implements CacheProvider { 12 | @Override 13 | public void put(String key, Serializable value) { 14 | put(key, value, CacheProperty.DEFAULT_EXPIRE_TIME); 15 | } 16 | 17 | @Override 18 | public Object update(String key, Serializable value) { 19 | return update(key, value, CacheProperty.DEFAULT_EXPIRE_TIME); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/provider/CacheProvider.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.provider; 2 | 3 | 4 | import java.io.Serializable; 5 | 6 | /** 7 | * 缓存策略,所有接口均返回Flowable,调用者可通过Flowable坚挺状态。 8 | * 9 | * @author bdq 10 | * @since 2020/2/17 11 | */ 12 | public interface CacheProvider { 13 | 14 | /** 15 | * 添加缓存 16 | * 17 | * @param key 18 | * @param value 19 | */ 20 | void put(String key, Serializable value); 21 | 22 | /** 23 | * 添加缓存 24 | * 25 | * @param key 26 | * @param value 27 | */ 28 | void put(String key, Serializable value, long expireTime); 29 | 30 | /** 31 | * 删除缓存 32 | * 33 | * @param key 34 | */ 35 | void remove(String key); 36 | 37 | /** 38 | * 更新缓存 39 | * 40 | * @param key 41 | * @param value 42 | * @return 旧的值 43 | */ 44 | Object update(String key, Serializable value); 45 | 46 | /** 47 | * 更新缓存 48 | * 49 | * @param key 50 | * @param value 51 | * @return 旧的值 52 | */ 53 | Object update(String key, Serializable value, long expireTime); 54 | 55 | /** 56 | * 获取缓存 57 | * 58 | * @param key 59 | * @return 缓存的值 60 | */ 61 | Object get(String key); 62 | 63 | /** 64 | * key对应的缓存是否存在 65 | * 66 | * @param key 67 | * @return 68 | */ 69 | boolean containKey(String key); 70 | 71 | /** 72 | * 清空所有缓存 73 | */ 74 | void clear(); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /festival-cache/src/main/java/cn/bdqfork/cache/provider/RedisCacheProvider.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.cache.provider; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/21 8 | */ 9 | public class RedisCacheProvider extends AbstractCacheProvider { 10 | @Override 11 | public void put(String key, Serializable value, long expireTime) { 12 | 13 | } 14 | 15 | @Override 16 | public void remove(String key) { 17 | 18 | } 19 | 20 | @Override 21 | public Object update(String key, Serializable value, long expireTime) { 22 | return null; 23 | } 24 | 25 | @Override 26 | public Object get(String key) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public boolean containKey(String key) { 32 | return false; 33 | } 34 | 35 | @Override 36 | public void clear() { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /festival-cache/src/main/resources/META-INF/extensions/cn.bdqfork.context.processor.LifeCycleProcessor: -------------------------------------------------------------------------------- 1 | cache=cn.bdqfork.cache.processor.CacheSupportProcessor -------------------------------------------------------------------------------- /festival-context/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | implementation "org.yaml:snakeyaml:${libs.snakeyaml}" 5 | implementation "javax.annotation:javax.annotation-api:${libs.jsr250}" 6 | 7 | api project(':festival-core') 8 | testImplementation project(':festival-aop') 9 | } 10 | 11 | publishing { 12 | publications { 13 | mavenJava(MavenPublication) { 14 | pom { 15 | description = 'Application context based on festival core!' 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.core.factory.BeanFactory; 5 | import cn.bdqfork.core.factory.ConfigurableBeanFactory; 6 | 7 | /** 8 | * 应用前后关系 9 | * 包含beanFactory的所有功能之外还提供了自动扫描资源目录的功能 10 | * 11 | * @author bdq 12 | * @since 2020/1/8 13 | */ 14 | public interface ApplicationContext extends BeanFactory { 15 | 16 | /** 17 | * 获取可配置bean工厂 18 | * 19 | * @return 可配置bean工厂 20 | */ 21 | ConfigurableBeanFactory getBeanFactory(); 22 | 23 | void start() throws Exception; 24 | 25 | void scan(String... scanPaths) throws BeansException; 26 | 27 | /** 28 | * 销毁容器中的单例类 29 | */ 30 | void close() throws Exception; 31 | 32 | boolean isClosed(); 33 | } 34 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/annotation/ComponentScan.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/30 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 12 | public @interface ComponentScan { 13 | String[] value(); 14 | } 15 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/aware/BeanFactoryAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.aware; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.core.factory.BeanFactory; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/21 9 | */ 10 | public interface BeanFactoryAware { 11 | void setBeanFactory(BeanFactory beanFactory) throws BeansException; 12 | } 13 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/aware/ClassLoaderAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.aware; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/16 8 | */ 9 | public interface ClassLoaderAware { 10 | void setClassLoader(ClassLoader classLoader) throws BeansException; 11 | } 12 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/aware/ResourceReaderAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.aware; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.context.configuration.reader.ResourceReader; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/26 9 | */ 10 | public interface ResourceReaderAware { 11 | void setResourceReader(ResourceReader resourceReader) throws BeansException; 12 | } 13 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/configuration/Configuration.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.configuration; 2 | 3 | import javax.inject.Named; 4 | import java.lang.annotation.*; 5 | 6 | /** 7 | * 标识该Bean为配置Bean 8 | * 9 | * @author bdq 10 | * @since 2020/1/9 11 | */ 12 | @Named 13 | @Documented 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 16 | public @interface Configuration { 17 | /** 18 | * 配置文件路径,如果指定了配置文件路径,则将会从指定配置文件中读取属性。 19 | */ 20 | String location() default ""; 21 | 22 | /** 23 | * 配置项的前缀 24 | */ 25 | String prefix() default ""; 26 | 27 | /** 28 | * @see javax.inject.Named 29 | */ 30 | String value() default ""; 31 | } 32 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/configuration/Value.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.configuration; 2 | 3 | 4 | import java.lang.annotation.*; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/9 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.FIELD) 13 | public @interface Value { 14 | /** 15 | * 配置前缀 16 | */ 17 | String value(); 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/configuration/reader/PropertiesResourceReader.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.configuration.reader; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.Properties; 6 | 7 | /** 8 | * @author fbw 9 | * @since 2020/1/9 10 | */ 11 | public class PropertiesResourceReader extends AbstractResourceReader { 12 | private Properties properties; 13 | 14 | public PropertiesResourceReader(String resourcePath) throws IOException { 15 | super(resourcePath); 16 | } 17 | 18 | public PropertiesResourceReader() throws IOException { 19 | this(DEFAULT_CONFIG_NAME + ".properties"); 20 | } 21 | 22 | @Override 23 | protected void load(String resourcePath) throws IOException { 24 | InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath); 25 | properties = new Properties(); 26 | if (inputStream != null) { 27 | properties.load(inputStream); 28 | } 29 | } 30 | 31 | @Override 32 | protected Object doReadProperty(String propertyName) { 33 | return properties.get(propertyName); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/configuration/reader/ResourceReader.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.configuration.reader; 2 | 3 | /** 4 | * 资源读取器,用于读取资源文件 5 | * 6 | * @author bdq 7 | * @since 2020/1/9 8 | */ 9 | public interface ResourceReader { 10 | String DEFAULT_CONFIG_NAME = "application"; 11 | 12 | /** 13 | * 根据配置项读取配置内容 14 | * 15 | * @param propertyName 资源名称 16 | * @return 配置项内容 17 | */ 18 | T readProperty(String propertyName, Class type, T defaultValue); 19 | 20 | /** 21 | * 根据配置项读取配置内容 22 | * 23 | * @param propertyName 资源名称 24 | * @param 泛型 25 | * @return 属性值 26 | */ 27 | T readProperty(String propertyName, Class type); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/configuration/reader/YamlResourceReader.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.configuration.reader; 2 | 3 | import org.yaml.snakeyaml.Yaml; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Collections; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/1/9 13 | */ 14 | public class YamlResourceReader extends AbstractResourceReader { 15 | private Map properties; 16 | 17 | public YamlResourceReader() throws IOException { 18 | this(DEFAULT_CONFIG_NAME + ".yaml"); 19 | } 20 | 21 | public YamlResourceReader(String resourcePath) throws IOException { 22 | super(resourcePath); 23 | } 24 | 25 | @Override 26 | protected void load(String resourcePath) throws IOException { 27 | Yaml yaml = new Yaml(); 28 | InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath); 29 | if (inputStream != null) { 30 | properties = yaml.load(inputStream); 31 | } else { 32 | properties = Collections.emptyMap(); 33 | } 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | @Override 38 | protected Object doReadProperty(String propertyName) { 39 | String[] keys = propertyName.split("\\."); 40 | int len = keys.length - 1; 41 | Map map = properties; 42 | for (int i = 0; i < len; i++) { 43 | if (map.containsKey(keys[i])) { 44 | map = (Map) map.get(keys[i]); 45 | } else { 46 | return null; 47 | } 48 | } 49 | return map.get(keys[len]); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/processor/AbstractLifeCycleProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.processor; 2 | 3 | import cn.bdqfork.context.ApplicationContext; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/22 8 | */ 9 | public abstract class AbstractLifeCycleProcessor implements LifeCycleProcessor { 10 | 11 | @Override 12 | public void beforeStart(ApplicationContext applicationContext) throws Exception { 13 | 14 | } 15 | 16 | @Override 17 | public void afterStart(ApplicationContext applicationContext) throws Exception { 18 | 19 | } 20 | 21 | @Override 22 | public void beforeStop(ApplicationContext applicationContext) throws Exception { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /festival-context/src/main/java/cn/bdqfork/context/processor/LifeCycleProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.context.processor; 2 | 3 | import cn.bdqfork.context.ApplicationContext; 4 | import cn.bdqfork.core.extension.SPI; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/22 9 | */ 10 | @SPI 11 | public interface LifeCycleProcessor { 12 | 13 | void beforeStart(ApplicationContext applicationContext) throws Exception; 14 | 15 | void afterStart(ApplicationContext applicationContext) throws Exception; 16 | 17 | void beforeStop(ApplicationContext applicationContext) throws Exception; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/SingletonBeanService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean; 2 | 3 | 4 | /** 5 | * @author fbw 6 | * @since 2020/1/5 7 | */ 8 | public interface SingletonBeanService { 9 | } 10 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/SingletonBeanServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | 6 | /** 7 | * @author fbw 8 | * @since 2020/1/5 9 | */ 10 | 11 | @Singleton 12 | @Named("singletonBeanServiceImpl") 13 | public class SingletonBeanServiceImpl implements SingletonBeanService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/exception/ErrorBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.exception; 2 | 3 | /** 4 | * @author fbw 5 | * @since 2020/1/13 6 | */ 7 | public interface ErrorBean { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/exception/InjectedBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.exception; 2 | 3 | import javax.inject.Named; 4 | 5 | /** 6 | * @author fbw 7 | * @since 2020/1/13 8 | */ 9 | @Named("wrongNameBean") 10 | public class InjectedBean { 11 | } 12 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/exception/ResolveExceptionBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.exception; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author fbw 9 | * @since 2020/1/13 10 | */ 11 | @Singleton 12 | @Named 13 | public class ResolveExceptionBean implements ErrorBean { 14 | 15 | @Inject 16 | public final InjectedBean injectedBean = null; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/exception/unsatisfied/UnsatisfiedBeanExceptionBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.exception.unsatisfied; 2 | 3 | import cn.bdqfork.model.bean.exception.InjectedBean; 4 | 5 | import javax.annotation.Resource; 6 | import javax.inject.Named; 7 | 8 | /** 9 | * @author fbw 10 | * @since 2020/1/13 11 | */ 12 | @Named 13 | public class UnsatisfiedBeanExceptionBean { 14 | 15 | 16 | private InjectedBean injectedBean; 17 | 18 | @Resource(name = "injectedBean") 19 | public void setInjectedBean(InjectedBean injectedBean) { 20 | this.injectedBean = injectedBean; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/exception/unsatisfied/WrongInjectedBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.exception.unsatisfied; 2 | 3 | import javax.inject.Named; 4 | 5 | /** 6 | * @author fbw 7 | * @since 2020/1/13 8 | */ 9 | 10 | 11 | @Named("injectedBean") 12 | public class WrongInjectedBean { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/normal/SingletonBeanService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.normal; 2 | 3 | 4 | /** 5 | * @author fbw 6 | * @since 2020/1/5 7 | */ 8 | 9 | public interface SingletonBeanService { 10 | } 11 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/bean/normal/SingletonBeanServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean.normal; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | 6 | /** 7 | * @author fbw 8 | * @since 2020/1/5 9 | */ 10 | 11 | @Singleton 12 | @Named 13 | public class SingletonBeanServiceImpl implements SingletonBeanService { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/collection/CollectionPropertyDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.collection; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/6 6 | */ 7 | public interface CollectionPropertyDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/collection/CollectionPropertyDaoImpl1.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.collection; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/6 9 | */ 10 | @Singleton 11 | @Named 12 | public class CollectionPropertyDaoImpl1 implements CollectionPropertyDao { 13 | } 14 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/collection/CollectionPropertyDaoImpl2.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.collection; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/6 9 | */ 10 | @Singleton 11 | @Named 12 | public class CollectionPropertyDaoImpl2 implements CollectionPropertyDao { 13 | } 14 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/collection/CollectionPropertyService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.collection; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/1/6 12 | */ 13 | @Singleton 14 | @Named 15 | public class CollectionPropertyService { 16 | @Inject 17 | private List daos; 18 | 19 | @Inject 20 | private Map daoMap; 21 | 22 | public List getDaos() { 23 | return daos; 24 | } 25 | 26 | public Map getDaoMap() { 27 | return daoMap; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/configuration/FactoryBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.configuration; 2 | 3 | /** 4 | * 工厂方法将要注册的bean 5 | * @author fbw 6 | * @since 2020/1/23 7 | */ 8 | public class FactoryBean { 9 | Server server; 10 | 11 | void setServer(Server server) { 12 | this.server = server; 13 | } 14 | 15 | public Server getServer() { 16 | return server; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "FactoryBean{" + 22 | "server=" + server + 23 | '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/configuration/FactoryMethodBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.configuration; 2 | 3 | 4 | import cn.bdqfork.context.configuration.Configuration; 5 | 6 | import javax.inject.Named; 7 | import javax.inject.Singleton; 8 | 9 | /** 10 | * 工厂类 11 | * 12 | * @author fbw 13 | * @since 2020/1/23 14 | */ 15 | 16 | @Singleton 17 | @Configuration 18 | public class FactoryMethodBean { 19 | 20 | @Named 21 | private FactoryBean getService(Server server) { 22 | FactoryBean factoryBean = new FactoryBean(); 23 | factoryBean.setServer(server); 24 | return factoryBean; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/configuration/Server.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.configuration; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/9 10 | */ 11 | @Singleton 12 | @Named 13 | public class Server { 14 | @Inject 15 | private ServerConfig serverConfig; 16 | 17 | public ServerConfig getServerConfig() { 18 | return serverConfig; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "Server{" + 24 | "serverConfig=" + serverConfig + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/configuration/ServerConfig.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.configuration; 2 | 3 | import cn.bdqfork.context.annotation.ComponentScan; 4 | import cn.bdqfork.context.configuration.Configuration; 5 | import cn.bdqfork.context.configuration.Value; 6 | 7 | import javax.inject.Singleton; 8 | import java.util.List; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/1/9 13 | */ 14 | @Singleton 15 | @ComponentScan("cn.bdqfork.model.bean.normal") 16 | @Configuration(prefix = "server") 17 | public class ServerConfig { 18 | @Value("localhost") 19 | private String localhost; 20 | @Value("port") 21 | private int port; 22 | @Value("names") 23 | private List names; 24 | 25 | public String getLocalhost() { 26 | return localhost; 27 | } 28 | 29 | public void setLocalhost(String localhost) { 30 | this.localhost = localhost; 31 | } 32 | 33 | public double getPort() { 34 | return port; 35 | } 36 | 37 | public void setPort(int port) { 38 | this.port = port; 39 | } 40 | 41 | public List getNames() { 42 | return names; 43 | } 44 | 45 | public void setNames(List names) { 46 | this.names = names; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "ServerConfig{" + 52 | "localhost='" + localhost + '\'' + 53 | ", port=" + port + 54 | ", names=" + names + 55 | '}'; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ConstructorCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ConstructorCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ConstructorCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class ConstructorCycleDaoImpl implements ConstructorCycleDao { 14 | private ConstructorCycleService service; 15 | 16 | @Inject 17 | public ConstructorCycleDaoImpl(ConstructorCycleService service) { 18 | this.service = service; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ConstructorCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ConstructorCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ConstructorCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class ConstructorCycleServiceImpl implements ConstructorCycleService { 14 | private ConstructorCycleDao constructorCycleDao; 15 | 16 | @Inject 17 | public ConstructorCycleServiceImpl(ConstructorCycleDao constructorCycleDao) { 18 | this.constructorCycleDao = constructorCycleDao; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/FieldCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface FieldCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/FieldCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class FieldCycleDaoImpl implements FieldCycleDao{ 14 | @Inject 15 | private FieldCycleService fieldCycleService; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/FieldCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface FieldCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/FieldCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class FieldCycleServiceImpl implements FieldCycleService { 14 | @Inject 15 | private FieldCycleDao fieldCycleDao; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeConstructorCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeConstructorCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeConstructorCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeConstructorCycleDaoImpl implements PrototypeConstructorCycleDao { 12 | private PrototypeConstructorCycleService service; 13 | 14 | @Inject 15 | public PrototypeConstructorCycleDaoImpl(PrototypeConstructorCycleService service) { 16 | this.service = service; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeConstructorCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeConstructorCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeConstructorCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeConstructorCycleServiceImpl implements PrototypeConstructorCycleService { 12 | private PrototypeConstructorCycleDao dao; 13 | 14 | @Inject 15 | public PrototypeConstructorCycleServiceImpl(PrototypeConstructorCycleDao dao) { 16 | this.dao = dao; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeFieldCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeFieldCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeFieldCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeFieldCycleDaoImpl implements PrototypeFieldCycleDao{ 12 | @Inject 13 | private PrototypeFieldCycleService service; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeFieldCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeFieldCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeFieldCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeFieldCycleServiceImpl implements PrototypeFieldCycleService { 12 | @Inject 13 | private PrototypeFieldCycleDao fieldCycleDao; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeSetterCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeSetterCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeSetterCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeSetterCycleDaoImpl implements PrototypeSetterCycleDao{ 12 | private PrototypeSetterCycleService service; 13 | 14 | @Inject 15 | public void setService(PrototypeSetterCycleService service) { 16 | this.service = service; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeSetterCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface PrototypeSetterCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/PrototypeSetterCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/17 9 | */ 10 | @Named 11 | public class PrototypeSetterCycleServiceImpl implements PrototypeSetterCycleService { 12 | private PrototypeSetterCycleDao dao; 13 | 14 | @Inject 15 | public void setDao(PrototypeSetterCycleDao dao) { 16 | this.dao = dao; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderCycleSetterDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ProviderCycleSetterDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderFieldCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ProviderFieldCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderFieldCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/18 10 | */ 11 | @Singleton 12 | @Named 13 | public class ProviderFieldCycleDaoImpl implements ProviderFieldCycleDao { 14 | @Inject 15 | private ProviderFieldCycleService providerFieldCycleService; 16 | } 17 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderFieldCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ProviderFieldCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderFieldCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/18 10 | */ 11 | @Singleton 12 | @Named 13 | public class ProviderFieldCycleServiceImpl implements ProviderFieldCycleService { 14 | @Inject 15 | private ProviderFieldCycleDao providerFieldCycleDao; 16 | } 17 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderSetterCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Provider; 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2019/12/17 11 | */ 12 | @Singleton 13 | @Named 14 | public class ProviderSetterCycleDaoImpl implements ProviderCycleSetterDao{ 15 | private Provider service; 16 | 17 | @Inject 18 | public void setService(Provider service) { 19 | this.service = service; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderSetterCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface ProviderSetterCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/ProviderSetterCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Provider; 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2019/12/17 11 | */ 12 | @Singleton 13 | @Named 14 | public class ProviderSetterCycleServiceImpl implements ProviderSetterCycleService { 15 | private Provider dao; 16 | 17 | @Inject 18 | public void setDao(Provider dao) { 19 | this.dao = dao; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/SetterCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface SetterCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/SetterCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class SetterCycleDaoImpl implements SetterCycleDao { 14 | private SetterCycleService service; 15 | 16 | @Inject 17 | public void setService(SetterCycleService service) { 18 | this.service = service; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/SetterCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface SetterCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/cycle/SetterCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.cycle; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class SetterCycleServiceImpl implements SetterCycleService { 14 | private SetterCycleDao dao; 15 | 16 | @Inject 17 | public void setDao(SetterCycleDao dao) { 18 | this.dao = dao; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250FieldCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface JSR250FieldCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250FieldCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | import cn.bdqfork.core.factory.DisposableBean; 4 | import cn.bdqfork.core.factory.InitializingBean; 5 | 6 | import javax.annotation.PostConstruct; 7 | import javax.annotation.PreDestroy; 8 | import javax.annotation.Resource; 9 | import javax.inject.Named; 10 | import javax.inject.Singleton; 11 | 12 | /** 13 | * @author bdq 14 | * @since 2019/12/17 15 | */ 16 | @Singleton 17 | @Named 18 | public class JSR250FieldCycleDaoImpl implements JSR250FieldCycleDao, InitializingBean, DisposableBean { 19 | 20 | @Resource(name = "jSR250FieldServiceImpl") 21 | private JSR250FieldService jsr250FieldService; 22 | 23 | @PostConstruct 24 | private void init() { 25 | System.out.println("init......"); 26 | } 27 | 28 | @PreDestroy 29 | private void preDestroy() { 30 | System.out.println("preDestroy......"); 31 | } 32 | 33 | @Override 34 | public void afterPropertiesSet() throws Exception { 35 | System.out.println("afterPropertiesSet......"); 36 | } 37 | 38 | @Override 39 | public void destroy() throws Exception { 40 | System.out.println("destroy......"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250FieldService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/19 6 | */ 7 | public interface JSR250FieldService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250FieldServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | import javax.annotation.Resource; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/19 10 | */ 11 | @Singleton 12 | @Named 13 | public class JSR250FieldServiceImpl implements JSR250FieldService { 14 | @Resource(type = JSR250FieldCycleDao.class) 15 | private JSR250FieldCycleDao jsr250FieldCycleDao; 16 | } 17 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250SetterCycleDao.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface JSR250SetterCycleDao { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250SetterCycleDaoImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | import javax.annotation.Resource; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class JSR250SetterCycleDaoImpl implements JSR250SetterCycleDao { 14 | private JSR250SetterCycleService service; 15 | 16 | @Resource(name = "jSR250SetterCycleServiceImpl") 17 | public void setService(JSR250SetterCycleService service) { 18 | this.service = service; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250SetterCycleService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public interface JSR250SetterCycleService { 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/jsr250/JSR250SetterCycleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.jsr250; 2 | 3 | import javax.annotation.Resource; 4 | import javax.inject.Named; 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2019/12/17 10 | */ 11 | @Singleton 12 | @Named 13 | public class JSR250SetterCycleServiceImpl implements JSR250SetterCycleService { 14 | private JSR250SetterCycleDao dao; 15 | 16 | @Resource 17 | public void setJSR250SetterCycleDaoImpl(JSR250SetterCycleDao dao) { 18 | this.dao = dao; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/processor/MyOrder1processor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.processor; 2 | 3 | import cn.bdqfork.core.annotation.Order; 4 | import cn.bdqfork.core.exception.BeansException; 5 | import cn.bdqfork.core.factory.processor.BeanPostProcessor; 6 | 7 | import javax.inject.Named; 8 | import javax.inject.Singleton; 9 | 10 | @Singleton 11 | @Named 12 | @Order(1) 13 | public class MyOrder1processor implements BeanPostProcessor { 14 | @Override 15 | public Object postProcessBeforeInitializtion(String beanName, Object bean) throws BeansException { 16 | System.out.println("MyOrder1processor Before Initializtion"); 17 | return bean; 18 | } 19 | 20 | @Override 21 | public Object postProcessAfterInitializtion(String beanName, Object bean) throws BeansException { 22 | System.out.println("MyOrder1processor After Initializtion"); 23 | return bean; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/processor/MyOrder2processor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.processor; 2 | 3 | import cn.bdqfork.core.annotation.Order; 4 | import cn.bdqfork.core.exception.BeansException; 5 | import cn.bdqfork.core.factory.processor.BeanPostProcessor; 6 | 7 | import javax.inject.Named; 8 | import javax.inject.Singleton; 9 | 10 | @Singleton 11 | @Named 12 | @Order(2) 13 | public class MyOrder2processor implements BeanPostProcessor { 14 | @Override 15 | public Object postProcessBeforeInitializtion(String beanName, Object bean) throws BeansException { 16 | System.out.println("MyOrder2processor Before Initializtion"); 17 | return bean; 18 | } 19 | 20 | @Override 21 | public Object postProcessAfterInitializtion(String beanName, Object bean) throws BeansException { 22 | System.out.println("MyOrder2processor After Initializtion"); 23 | return bean; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/processor/MyOrderProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.processor; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.core.factory.processor.BeanPostProcessor; 5 | 6 | import javax.inject.Named; 7 | 8 | 9 | @Named 10 | public class MyOrderProcessor implements BeanPostProcessor { 11 | @Override 12 | public Object postProcessBeforeInitializtion(String beanName, Object bean) throws BeansException { 13 | System.out.println("MyOrderProcessor Before Initializtion"); 14 | return bean; 15 | } 16 | 17 | @Override 18 | public Object postProcessAfterInitializtion(String beanName, Object bean) throws BeansException { 19 | System.out.println("MyOrderProcessor After Initializtion"); 20 | return bean; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/processor/TestBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.processor; 2 | 3 | import javax.inject.Named; 4 | 5 | @Named 6 | public class TestBean { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/proxy/AopProxyTestBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.proxy; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2019/12/31 9 | */ 10 | @Singleton 11 | @Named 12 | public class AopProxyTestBean { 13 | public String testAop() { 14 | System.out.println("processing"); 15 | return "ok"; 16 | } 17 | 18 | public String testThrowing() { 19 | System.out.println(1 / 0); 20 | return "ok"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/proxy/Log.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.proxy; 2 | 3 | import cn.bdqfork.core.annotation.Order; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.*; 7 | 8 | import javax.inject.Named; 9 | import javax.inject.Singleton; 10 | 11 | /** 12 | * @author bdq 13 | * @since 2019/12/31 14 | */ 15 | @Singleton 16 | @Named 17 | @Aspect 18 | @Order(3) 19 | public class Log { 20 | @Before("pointcut()") 21 | public void before(JoinPoint joinPoint) { 22 | System.out.println("执行前置通知方法"); 23 | } 24 | 25 | @AfterReturning(value = "pointcut()", returning = "result") 26 | public void after(JoinPoint joinPoint, Object result) { 27 | System.out.println("执行后置通知方法,return : " + result); 28 | } 29 | 30 | @Around("execution(cn.bdqfork.model.proxy.*)") 31 | public Object myAround(ProceedingJoinPoint pjp) throws Throwable { 32 | System.out.println("执行环绕通知方法,目标方法执行之前"); 33 | Object result = pjp.proceed(); 34 | System.out.println("执行环绕通知方法,目标方法执行之后"); 35 | if (result != null) { //可以修改目标方法的返回结果 36 | result = ((String) result).toUpperCase(); 37 | } 38 | return result; 39 | } 40 | 41 | @AfterThrowing(value = "pointcut()", throwing = "ex") 42 | public void afterThrowing(JoinPoint joinPoint, Exception ex) { 43 | System.out.println("执行异常抛出通知方法,Exception : " + ex); 44 | } 45 | 46 | @Pointcut("execution(cn.bdqfork.model.proxy.*)") 47 | public void pointcut() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/proxy/OrderLog1.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.proxy; 2 | 3 | import cn.bdqfork.core.annotation.Order; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.*; 7 | 8 | import javax.inject.Named; 9 | import javax.inject.Singleton; 10 | 11 | @Singleton 12 | @Named 13 | @Aspect 14 | @Order(1) 15 | public class OrderLog1 { 16 | 17 | @Before("pointcut()") 18 | public void before(JoinPoint joinPoint) { 19 | System.out.println("执行前置通知方法Order1"); 20 | } 21 | 22 | @AfterReturning(value = "pointcut()", returning = "result") 23 | public void after(JoinPoint joinPoint, Object result) { 24 | System.out.println("执行后置通知方法Order1,return : " + result); 25 | } 26 | 27 | @Around("execution(cn.bdqfork.model.proxy.*)") 28 | public Object myAround(ProceedingJoinPoint pjp) throws Throwable { 29 | System.out.println("执行环绕通知方法Order1,目标方法执行之前"); 30 | Object result = pjp.proceed(); 31 | System.out.println("执行环绕通知方法Order1,目标方法执行之后"); 32 | if (result != null) { //可以修改目标方法的返回结果 33 | result = ((String) result).toUpperCase(); 34 | } 35 | return result; 36 | } 37 | 38 | @AfterThrowing(value = "pointcut()", throwing = "ex") 39 | public void afterThrowing(JoinPoint joinPoint, Exception ex) { 40 | System.out.println("执行异常抛出通知方法Order1,Exception : " + ex); 41 | } 42 | 43 | 44 | @Pointcut("execution(cn.bdqfork.model.proxy.*)") 45 | public void pointcut() { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /festival-context/src/test/java/cn/bdqfork/model/proxy/OrderLog2.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.proxy; 2 | 3 | import cn.bdqfork.core.annotation.Order; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Before; 7 | import org.aspectj.lang.annotation.Pointcut; 8 | 9 | import javax.inject.Named; 10 | import javax.inject.Singleton; 11 | 12 | @Singleton 13 | @Named 14 | @Aspect 15 | @Order(2) 16 | public class OrderLog2 { 17 | 18 | @Before("pointcut()") 19 | public void before(JoinPoint joinPoint) { 20 | System.out.println("执行前置通知方法Order2"); 21 | } 22 | 23 | @Pointcut("execution(cn.bdqfork.model.proxy.*)") 24 | public void pointcut() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /festival-context/src/test/resources/application-dev.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | localhost: 127.0.0.1 3 | port: 80 4 | names: 5 | - name1 6 | - name2 -------------------------------------------------------------------------------- /festival-context/src/test/resources/application.yaml: -------------------------------------------------------------------------------- 1 | profile: dev -------------------------------------------------------------------------------- /festival-context/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /festival-context/src/test/resources/testReadProperties.properties: -------------------------------------------------------------------------------- 1 | server.int = 5 2 | server.long = 1 3 | server.float = 2.234 4 | server.char = b 5 | server.double = 1.234 6 | server.boolean = true 7 | jdbc.driver = com.mysql.cj.jdbc.driver 8 | jdbc.port = 3306 9 | web.localhost = 127.0.0.1 10 | web.port = 8080 11 | -------------------------------------------------------------------------------- /festival-context/src/test/resources/testReadYaml.yaml: -------------------------------------------------------------------------------- 1 | test: 2 | int: 5 3 | float: 1.234 4 | byte: 1 5 | char: a 6 | boolean: true 7 | double: 2.234 8 | jdbc: 9 | driver: com.mysql.cj.jdbc.driver 10 | port: 3306 11 | server: 12 | localhost: 127.0.0.1 13 | port: 8080 -------------------------------------------------------------------------------- /festival-core/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | api "javax.inject:javax.inject:${libs.jsr330}" 5 | implementation "org.javassist:javassist:${libs.javassist}" 6 | } 7 | 8 | publishing { 9 | publications { 10 | mavenJava(MavenPublication) { 11 | pom { 12 | description = 'IoC core factories!' 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/annotation/Optimize.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 该类应用于需要强制被CGlib代理的实例 7 | * 8 | * @author bdq 9 | * @since 2020/1/29 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 14 | public @interface Optimize { 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/annotation/Order.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 表示bean的优先级,用户实现的value必须大于0否则无效,数字越小优先级越高,未标记或未注明value的bean优先级为最低 7 | */ 8 | 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | public @interface Order { 13 | 14 | int value() default Integer.MAX_VALUE; 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/BeansException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-07-30 6 | */ 7 | public class BeansException extends Exception { 8 | public BeansException(String message) { 9 | super(message); 10 | } 11 | 12 | public BeansException(Throwable cause) { 13 | super(cause); 14 | } 15 | 16 | public BeansException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/CircularDependencyException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public class CircularDependencyException extends BeansException { 8 | public CircularDependencyException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/ConflictedBeanException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-02-14 6 | */ 7 | public class ConflictedBeanException extends BeansException { 8 | 9 | public ConflictedBeanException(String message) { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/FailedInjectedConstructorException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-07-28 6 | */ 7 | public class FailedInjectedConstructorException extends BeansException { 8 | public FailedInjectedConstructorException(Throwable cause) { 9 | super(cause); 10 | } 11 | 12 | public FailedInjectedConstructorException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/FailedInjectedFieldException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-02-14 6 | */ 7 | public class FailedInjectedFieldException extends BeansException { 8 | public FailedInjectedFieldException(String message) { 9 | super(message); 10 | } 11 | 12 | public FailedInjectedFieldException(Throwable cause) { 13 | super(cause); 14 | } 15 | 16 | public FailedInjectedFieldException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/FailedInjectedMethodException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-02-14 6 | */ 7 | public class FailedInjectedMethodException extends BeansException { 8 | 9 | public FailedInjectedMethodException(String message) { 10 | super(message); 11 | } 12 | 13 | public FailedInjectedMethodException(Throwable cause) { 14 | super(cause); 15 | } 16 | 17 | public FailedInjectedMethodException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/NoSuchBeanException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/18 6 | */ 7 | public class NoSuchBeanException extends BeansException { 8 | public NoSuchBeanException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/ResolvedException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-07-30 6 | */ 7 | public class ResolvedException extends BeansException { 8 | public ResolvedException(String message) { 9 | super(message); 10 | } 11 | 12 | public ResolvedException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public ResolvedException(Throwable cause) { 17 | super(cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/ScopeException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-07-30 6 | */ 7 | public class ScopeException extends ResolvedException { 8 | public ScopeException(String message) { 9 | super(message); 10 | } 11 | 12 | public ScopeException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public ScopeException(Throwable cause) { 17 | super(cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/exception/UnsatisfiedBeanException.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.exception; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019-02-13 6 | */ 7 | public class UnsatisfiedBeanException extends BeansException { 8 | public UnsatisfiedBeanException(String message) { 9 | super(message); 10 | } 11 | 12 | public UnsatisfiedBeanException(Throwable cause) { 13 | super(cause); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/extension/SPI.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.extension; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 注解在扩展类上,表示可以扩展 7 | * 8 | * @author bdq 9 | * @since 2019/9/21 10 | */ 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface SPI { 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/AutoInjectedBeanfactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.core.exception.UnsatisfiedBeanException; 5 | 6 | /** 7 | * 实现自动注入Bean工厂 8 | * 9 | * @author bdq 10 | * @since 2019/12/16 11 | */ 12 | public interface AutoInjectedBeanfactory extends ConfigurableBeanFactory { 13 | 14 | /** 15 | * 生成bean对象 16 | * 17 | * @param beanName bean名称 18 | * @return Object bean实例 19 | * @throws BeansException 20 | */ 21 | Object createBean(String beanName) throws BeansException; 22 | 23 | /** 24 | * 自动注入 25 | * 26 | * @param beanName bean名称 27 | * @param bean bean实例 28 | * @throws BeansException 29 | */ 30 | void autoInjected(String beanName, Object bean) throws BeansException; 31 | 32 | /** 33 | * 解决依赖 34 | * @param injectedPoint 注入点实例 35 | * @param beanName bean名称 36 | * @return 完成注入的bean对象 37 | * @throws UnsatisfiedBeanException 根据bean名称无法找到bean 38 | */ 39 | Object resovleDependence(InjectedPoint injectedPoint, String beanName) throws UnsatisfiedBeanException; 40 | 41 | /** 42 | * 解决多重依赖 43 | * @param multInjectedPoint 多重依赖注入点 44 | * @param beanName bean名称 45 | * @return 完成注入的bean对象数组 46 | * @throws UnsatisfiedBeanException 47 | */ 48 | Object[] resovleMultDependence(MultInjectedPoint multInjectedPoint, String beanName) throws UnsatisfiedBeanException; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/BeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Bean工厂以及容器 9 | * 10 | * @author bdq 11 | * @since 2019-07-30 12 | */ 13 | public interface BeanFactory { 14 | 15 | /** 16 | * 根据beanName获取代理实例 17 | * 18 | * @param beanName Bean名称 19 | * @return Object Bean实例 20 | */ 21 | T getBean(String beanName) throws BeansException; 22 | 23 | /** 24 | * 根据beanName获取代理实例 25 | * 26 | * @param beanName Bean名称 27 | * @return Object Bean实例 28 | */ 29 | T getBean(String beanName, Object[] args) throws BeansException; 30 | 31 | /** 32 | * 获取clazz匹配代理实例,如果有多个实例,跑出异常 33 | * 34 | * @param clazz class类型 35 | * @return Object Bean实例 36 | */ 37 | T getBean(Class clazz) throws BeansException; 38 | 39 | /** 40 | * 获取第一个与clazz匹配代理实例 41 | * 42 | * @param clazz class类型 43 | * @return Object Bean实例 44 | */ 45 | T getSpecificBean(String beanName, Class clazz) throws BeansException; 46 | 47 | /** 48 | * 获取与clazz匹配的实例 49 | * 50 | * @param clazz class类型 51 | * @return Map Bean实例 52 | */ 53 | Map getBeans(Class clazz) throws BeansException; 54 | 55 | boolean containBean(String beanName); 56 | 57 | boolean isSingleton(String beanName) throws BeansException; 58 | 59 | boolean isPrototype(String beanName) throws BeansException; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/BeanNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | /** 4 | * beanName生成器 5 | * 6 | * @author bdq 7 | * @since 2019-02-07 8 | */ 9 | public interface BeanNameGenerator { 10 | /** 11 | * 生成beanName 12 | * 13 | * @param clazz 目标类型 14 | * @return String beanName 15 | */ 16 | String generateBeanName(Class clazz); 17 | } 18 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/ConfigurableBeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | import cn.bdqfork.core.factory.processor.BeanPostProcessor; 4 | import cn.bdqfork.core.factory.registry.BeanDefinitionRegistry; 5 | import cn.bdqfork.core.factory.registry.SingletonBeanRegistry; 6 | 7 | /** 8 | * 可配置的Bean工厂 9 | * @author bdq 10 | * @since 2019/12/15 11 | */ 12 | public interface ConfigurableBeanFactory extends BeanFactory, SingletonBeanRegistry, BeanDefinitionRegistry { 13 | 14 | /** 15 | * 设置委托工厂 16 | * 17 | * @param beanFactory bean工厂 18 | */ 19 | void setParentBeanFactory(BeanFactory beanFactory); 20 | 21 | /** 22 | * 获取委托工厂 23 | * 24 | * @return BeanFactory 25 | */ 26 | BeanFactory getParentBeanFactory(); 27 | 28 | /** 29 | * 添加Bean后置处理器 30 | * 31 | * @param beanPostProcessor 32 | */ 33 | void addPostBeanProcessor(BeanPostProcessor beanPostProcessor); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/DisposableBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | /** 4 | * 一次性的bean 5 | * 6 | * @author bdq 7 | * @since 2020/1/7 8 | */ 9 | public interface DisposableBean { 10 | /** 11 | * 销毁方法 12 | * 13 | * @throws Exception 异常 14 | */ 15 | void destroy() throws Exception; 16 | } 17 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/InitializingBean.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/7 6 | */ 7 | public interface InitializingBean { 8 | void afterPropertiesSet() throws Exception; 9 | } 10 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/JSR250BeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | 5 | /** 6 | * 遵循jsr250的bean工厂 7 | * @author bdq 8 | * @since 2019/12/18 9 | */ 10 | public interface JSR250BeanFactory extends ConfigurableBeanFactory { 11 | 12 | /** 13 | * 执行预生成方法 14 | * 15 | * @param beanName bean名称 16 | * @param bean bean对象 17 | * @throws BeansException 18 | */ 19 | void executePostConstuct(String beanName, Object bean) throws BeansException; 20 | 21 | /** 22 | * 执行预销毁方法 23 | * 24 | * @param beanName bean名称 25 | * @param bean bean对象 26 | * @throws BeansException 27 | */ 28 | void executePreDestroy(String beanName, Object bean) throws BeansException; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/SimpleBeanNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory; 2 | 3 | import cn.bdqfork.core.util.StringUtils; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2019-02-07 8 | */ 9 | public class SimpleBeanNameGenerator implements BeanNameGenerator { 10 | /** 11 | * 生成BeanName 12 | * 13 | * @param clazz 目标类型 14 | * @return String 简单类的名首字符小写形式 15 | */ 16 | @Override 17 | public String generateBeanName(Class clazz) { 18 | String className = clazz.getSimpleName(); 19 | return StringUtils.makeInitialLowercase(className); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/definition/ManagedBeanDefinition.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.definition; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/19 6 | */ 7 | public class ManagedBeanDefinition extends BeanDefinition { 8 | /** 9 | * 初始化方法名 10 | */ 11 | private String initializingMethod; 12 | /** 13 | * 销毁方法名 14 | */ 15 | private String destroyMethod; 16 | 17 | public ManagedBeanDefinition(String beanName, Class beanClass) { 18 | super(beanName, beanClass); 19 | } 20 | 21 | public ManagedBeanDefinition(String beanName, Class beanClass, String scope) { 22 | super(beanName, beanClass, scope); 23 | } 24 | 25 | public String getInitializingMethod() { 26 | return initializingMethod; 27 | } 28 | 29 | public void setInitializingMethod(String initializingMethod) { 30 | this.initializingMethod = initializingMethod; 31 | } 32 | 33 | public String getDestroyMethod() { 34 | return destroyMethod; 35 | } 36 | 37 | public void setDestroyMethod(String destroyMethod) { 38 | this.destroyMethod = destroyMethod; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/processor/BeanFactoryPostProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.processor; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.core.factory.ConfigurableBeanFactory; 5 | 6 | /** 7 | * bean工厂后置处理器自定义接口,功能交给用户来实现 8 | * 9 | * @author bdq 10 | * @since 2020/1/7 11 | */ 12 | public interface BeanFactoryPostProcessor { 13 | /** 14 | * 执行后置处理 15 | * 16 | * @param beanFactory 可配置bean工厂 17 | * @throws BeansException 异常 18 | */ 19 | void postProcessBeanFactory(ConfigurableBeanFactory beanFactory) throws BeansException; 20 | } 21 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/processor/BeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.processor; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/7 8 | */ 9 | public interface BeanPostProcessor { 10 | 11 | Object postProcessBeforeInitializtion(String beanName, Object bean) throws BeansException; 12 | 13 | Object postProcessAfterInitializtion(String beanName, Object bean) throws BeansException; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/processor/OrderAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.processor; 2 | 3 | /** 4 | * 表示bean的优先级,用户实现的value必须大于0否则无效,数字越小优先级越高,未标记或未注明value的bean优先级为最低 5 | * @author bdq 6 | * @since 2020/1/29 7 | */ 8 | public interface OrderAware { 9 | int getOrder(); 10 | } 11 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/registry/BeanDefinitionRegistry.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.registry; 2 | 3 | import cn.bdqfork.core.factory.definition.BeanDefinition; 4 | import cn.bdqfork.core.exception.BeansException; 5 | import cn.bdqfork.core.exception.ConflictedBeanException; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2019/12/16 13 | */ 14 | public interface BeanDefinitionRegistry extends Registry { 15 | 16 | boolean isSingleton(String beanName) throws BeansException; 17 | 18 | boolean isPrototype(String beanName) throws BeansException; 19 | 20 | /** 21 | * 将Bean描述注册到容器中 22 | * 23 | * @param beanName Bean名称 24 | * @param beanDefinition Bean的描述信息 25 | * @throws ConflictedBeanException Bean冲突异常 26 | */ 27 | void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeansException; 28 | 29 | /** 30 | * 获取所有BeanDefinition 31 | * 32 | * @return Map 33 | */ 34 | BeanDefinition getBeanDefinition(String beanName); 35 | 36 | /** 37 | * 获取所有BeanDefinition 38 | * 39 | * @return Map 40 | */ 41 | List getBeanDefinitions(Class beanType); 42 | 43 | /** 44 | * 获取所有BeanDefinition 45 | * 46 | * @return Map 47 | */ 48 | Map getBeanDefinitions(); 49 | 50 | boolean containBeanDefinition(String beanName); 51 | 52 | void clearAllBeanDefinitions(); 53 | } 54 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/registry/Registry.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.registry; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2019/12/16 6 | */ 7 | public interface Registry { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/factory/registry/SingletonBeanRegistry.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.factory.registry; 2 | 3 | /** 4 | * 实现SingletonBeanRegistry接口的类,需要实现对单实例的bean进行管理的方法。 5 | * 对于非单例的bean,不需要进行管理。 6 | * 7 | * @author bdq 8 | * @since 2019/12/16 9 | */ 10 | public interface SingletonBeanRegistry extends Registry { 11 | 12 | /** 13 | * 注册一个实例,beanName应该具有唯一性,不同注册相同的实例。 14 | * 15 | * @param beanName bean的名称 16 | * @param bean bean实例 17 | */ 18 | void registerSingleton(String beanName, Object bean); 19 | 20 | /** 21 | * 获取一个实例 22 | * 23 | * @param beanName bean的名称 24 | * @return 实例 25 | */ 26 | Object getSingleton(String beanName); 27 | 28 | /** 29 | * 删除一个实例 30 | * 31 | * @param beanName bean的名称 32 | */ 33 | void destroySingleton(String beanName); 34 | 35 | /** 36 | * 是否包含实例 37 | * 38 | * @param beanName bean的名称 39 | * @return 是否包含实例 40 | */ 41 | boolean containSingleton(String beanName); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/proxy/FestivalProxy.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.proxy; 2 | 3 | /** 4 | * 标记接口,所有的代理类都需要实现 5 | * 6 | * @author bdq 7 | * @since 2020/1/25 8 | */ 9 | public interface FestivalProxy { 10 | } 11 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/proxy/TargetClassAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.proxy; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/25 6 | */ 7 | public interface TargetClassAware { 8 | Class getTargetClass(); 9 | } 10 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/util/AopUtils.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.util; 2 | 3 | 4 | import cn.bdqfork.core.proxy.FestivalProxy; 5 | import cn.bdqfork.core.proxy.TargetClassAware; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/25 10 | */ 11 | public class AopUtils { 12 | /** 13 | * 获取代理类的真实类型 14 | * 15 | * @param candidate 需要获取真实类型的对象 16 | * @return 真实类型 17 | */ 18 | public static Class getTargetClass(Object candidate) { 19 | if (isProxy(candidate) && candidate instanceof TargetClassAware) { 20 | return ((TargetClassAware) candidate).getTargetClass(); 21 | } 22 | return candidate.getClass(); 23 | } 24 | 25 | /** 26 | * 是否是代理类 27 | * 28 | * @param candidate 待验证实例 29 | * @return 是否是代理类 30 | */ 31 | public static boolean isProxy(Object candidate) { 32 | return candidate instanceof FestivalProxy; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /festival-core/src/main/java/cn/bdqfork/core/util/FileUtils.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.util; 2 | 3 | import java.io.File; 4 | import java.net.URL; 5 | 6 | /** 7 | * FileUtil 8 | */ 9 | public class FileUtils { 10 | 11 | public static String getUniformAbsolutePath(File file) { 12 | return file.getAbsolutePath().replaceAll("\\\\", "\\/"); 13 | } 14 | 15 | public static URL loadResourceByPath(String path) { 16 | return FileUtils.class.getClassLoader().getResource(path); 17 | } 18 | 19 | public static boolean isResourceExists(String path) { 20 | return FileUtils.class.getClassLoader().getResource(path) != null; 21 | } 22 | } -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/core/extension/ExtensionLoaderTest.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.extension; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class ExtensionLoaderTest { 8 | 9 | @Test 10 | public void getExtension() { 11 | ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(IExtensionTest.class); 12 | IExtensionTest iExtensionTest = extensionLoader.getExtension("imp1"); 13 | assert iExtensionTest != null; 14 | } 15 | 16 | @Test 17 | public void getExtensions() { 18 | ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(IExtensionTest.class); 19 | assertEquals(extensionLoader.getExtensions().size(), 2); 20 | } 21 | } -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/core/extension/ExtensionTestImpl1.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.extension; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/22 6 | */ 7 | public class ExtensionTestImpl1 implements IExtensionTest { 8 | } 9 | -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/core/extension/ExtensionTestImpl2.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.extension; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/22 6 | */ 7 | public class ExtensionTestImpl2 implements IExtensionTest { 8 | } 9 | -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/core/extension/IExtensionTest.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.extension; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/22 6 | */ 7 | @SPI 8 | public interface IExtensionTest { 9 | } 10 | -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/core/util/ReflectUtilsTest.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.core.util; 2 | 3 | import cn.bdqfork.core.factory.BeanFactory; 4 | import cn.bdqfork.core.factory.DefaultBeanFactory; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertTrue; 8 | 9 | public class ReflectUtilsTest { 10 | 11 | @Test 12 | public void isSubType() { 13 | assertTrue(ReflectUtils.isSubType(DefaultBeanFactory.class, BeanFactory.class)); 14 | } 15 | } -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/model/bean/SingletonBeanService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean; 2 | 3 | 4 | /** 5 | * @author fbw 6 | * @since 2020/1/5 7 | */ 8 | public interface SingletonBeanService { 9 | } 10 | -------------------------------------------------------------------------------- /festival-core/src/test/java/cn/bdqfork/model/bean/SingletonBeanServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.model.bean; 2 | 3 | import javax.inject.Named; 4 | 5 | /** 6 | * @author fbw 7 | * @since 2020/1/5 8 | */ 9 | 10 | @Named("singletonBeanServiceImpl") 11 | public class SingletonBeanServiceImpl implements SingletonBeanService { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /festival-core/src/test/resources/META-INF/extensions/cn.bdqfork.core.extension.IExtensionTest: -------------------------------------------------------------------------------- 1 | imp1=cn.bdqfork.core.extension.ExtensionTestImpl1 2 | imp2=cn.bdqfork.core.extension.ExtensionTestImpl2 -------------------------------------------------------------------------------- /festival-core/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /festival-example/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | subprojects { 4 | dependencies { 5 | implementation "io.vertx:vertx-auth-shiro:${libs.vertx}" 6 | implementation "joda-time:joda-time:${libs.joda}" 7 | } 8 | } 9 | 10 | tasks.withType(PublishToMavenRepository) { 11 | onlyIf { 12 | false 13 | } 14 | } 15 | tasks.withType(PublishToMavenLocal) { 16 | onlyIf { 17 | false 18 | } 19 | } -------------------------------------------------------------------------------- /festival-example/kotlin-web/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.github.johnrengelman.shadow" 2 | def libs = rootProject.ext.libraries 3 | 4 | dependencies { 5 | implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${libs.jackson}" 6 | implementation "io.vertx:vertx-web-templ-thymeleaf:${libs.vertx}" 7 | implementation project(':festival-kotlin-web') 8 | // implementation project(':festival-aop') 9 | } 10 | 11 | tasks.withType(PublishToMavenRepository) { 12 | onlyIf { 13 | false 14 | } 15 | } 16 | tasks.withType(PublishToMavenLocal) { 17 | onlyIf { 18 | false 19 | } 20 | } -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/Hello.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example; 2 | 3 | import cn.bdqfork.kotlin.web.WebApplication; 4 | import cn.bdqfork.kotlin.web.route.ModelAndView; 5 | import cn.bdqfork.kotlin.web.route.annotation.GetMapping; 6 | import cn.bdqfork.kotlin.web.route.annotation.RouteController; 7 | 8 | import javax.inject.Singleton; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/2/16 13 | */ 14 | @Singleton 15 | @RouteController 16 | public class Hello { 17 | 18 | @GetMapping("/hello") 19 | public String hello() { 20 | return "hello festival"; 21 | } 22 | 23 | @GetMapping("/template") 24 | public ModelAndView template() { 25 | ModelAndView modelAndView = new ModelAndView("index"); 26 | modelAndView.add("test", "hello template"); 27 | return modelAndView; 28 | } 29 | 30 | public static void main(String[] args) throws Exception { 31 | WebApplication.Companion.run(Hello.class); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/config/AuthConfig.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.config; 2 | 3 | import cn.bdqfork.context.configuration.Configuration; 4 | import cn.bdqfork.kotlin.web.route.filter.AuthFilter; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.json.JsonObject; 7 | import io.vertx.ext.auth.AuthProvider; 8 | import io.vertx.ext.auth.shiro.ShiroAuth; 9 | import io.vertx.ext.auth.shiro.ShiroAuthOptions; 10 | import io.vertx.ext.auth.shiro.ShiroAuthRealmType; 11 | import io.vertx.ext.web.handler.AuthHandler; 12 | import io.vertx.ext.web.handler.BasicAuthHandler; 13 | 14 | import javax.inject.Named; 15 | import javax.inject.Singleton; 16 | 17 | /** 18 | * @author bdq 19 | * @since 2020/1/28 20 | */ 21 | @Singleton 22 | @Configuration 23 | public class AuthConfig { 24 | 25 | @Singleton 26 | @Named 27 | public AuthProvider authProvider(Vertx vertx) { 28 | JsonObject config = new JsonObject().put("properties_path", "classpath:vertx-users.properties"); 29 | ShiroAuthOptions options = new ShiroAuthOptions().setType(ShiroAuthRealmType.PROPERTIES).setConfig(config); 30 | return ShiroAuth.create(vertx, options); 31 | } 32 | 33 | @Singleton 34 | @Named 35 | public AuthHandler authHandler(AuthProvider authProvider) { 36 | return BasicAuthHandler.create(authProvider); 37 | } 38 | 39 | @Singleton 40 | @Named 41 | public AuthFilter authFilter() { 42 | AuthFilter authFilter = new AuthFilter(); 43 | authFilter.setDeniedHandler(routingContext -> { 44 | routingContext.response().setStatusCode(403).end("you have not permissions!"); 45 | }); 46 | return authFilter; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/domain/IService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/26 6 | */ 7 | public interface IService { 8 | String getUserName(String username); 9 | 10 | void testError(String username); 11 | } 12 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/domain/ServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | import cn.bdqfork.kotlin.web.annotation.VerticleMapping; 4 | 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/26 10 | */ 11 | @Singleton 12 | @VerticleMapping("ServiceImpl1") 13 | public class ServiceImpl implements IService { 14 | @Override 15 | public String getUserName(String username) { 16 | return username; 17 | } 18 | 19 | @Override 20 | public void testError(String username) { 21 | System.out.println( 1 / 0); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/domain/ServiceImpl2.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | import cn.bdqfork.kotlin.web.annotation.VerticleMapping; 4 | 5 | import javax.inject.Singleton; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/26 10 | */ 11 | @Singleton 12 | @VerticleMapping("ServiceImpl2") 13 | public class ServiceImpl2 implements IService { 14 | @Override 15 | public String getUserName(String username) { 16 | return username; 17 | } 18 | 19 | @Override 20 | public void testError(String username) { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/java/cn/bdqfork/kotlin/example/model/User.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | 5 | import java.util.Date; 6 | 7 | public class User { 8 | 9 | int id; 10 | String username; 11 | boolean active; 12 | @JsonFormat(pattern = "YYYY") 13 | Date createDate; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public User setId(int id) { 20 | this.id = id; 21 | return this; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public User setUsername(String username) { 29 | this.username = username; 30 | return this; 31 | } 32 | 33 | public boolean isActive() { 34 | return active; 35 | } 36 | 37 | public User setActive(boolean active) { 38 | this.active = active; 39 | return this; 40 | } 41 | 42 | public Date getCreateDate() { 43 | return createDate; 44 | } 45 | 46 | public User setCreateDate(Date createDate) { 47 | this.createDate = createDate; 48 | return this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | host: 127.0.0.1 3 | port: 8080 4 | http2: 5 | enable: true 6 | ssl: 7 | enable: false 8 | path: test.jks 9 | password: '123456' 10 | uploads: 11 | limit: 2147483648 12 | static: 13 | enable: true 14 | cache: 15 | enable: true 16 | template: 17 | enable: true 18 | type: thymeleaf 19 | suffix: ".html" -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | hello -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Thymeleaf测试页 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/test.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/festival-example/kotlin-web/src/main/resources/test.jks -------------------------------------------------------------------------------- /festival-example/kotlin-web/src/main/resources/vertx-users.properties: -------------------------------------------------------------------------------- 1 | user.tim = mypassword,administrator,developer 2 | user.bob = hispassword,developer 3 | user.joe = anotherpassword,manager 4 | role.administrator=* 5 | role.manager=play_golf,say_buzzwords 6 | role.developer=do_actual_work -------------------------------------------------------------------------------- /festival-example/web/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.github.johnrengelman.shadow" 2 | 3 | def libs = rootProject.ext.libraries 4 | 5 | dependencies { 6 | implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${libs.jackson}" 7 | implementation "io.vertx:vertx-web-templ-thymeleaf:${libs.vertx}" 8 | implementation project(':festival-web') 9 | implementation project(':festival-aop') 10 | } 11 | 12 | tasks.withType(PublishToMavenRepository) { 13 | onlyIf { 14 | false 15 | } 16 | } 17 | tasks.withType(PublishToMavenLocal) { 18 | onlyIf { 19 | false 20 | } 21 | } -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/Hello.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example; 2 | 3 | import cn.bdqfork.web.WebApplication; 4 | import cn.bdqfork.web.route.ModelAndView; 5 | import cn.bdqfork.web.route.annotation.GetMapping; 6 | import cn.bdqfork.web.route.annotation.RouteController; 7 | 8 | import javax.inject.Singleton; 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/2/16 13 | */ 14 | @Singleton 15 | @RouteController 16 | public class Hello { 17 | 18 | @GetMapping("/hello") 19 | public String hello() { 20 | return "hello festival"; 21 | } 22 | 23 | @GetMapping("/thymeleaf") 24 | public ModelAndView testThymeleaf() { 25 | ModelAndView modelAndView = new ModelAndView("thymeleaf"); 26 | modelAndView.add("hello", "hello thymeleaf"); 27 | return modelAndView; 28 | } 29 | 30 | @GetMapping("/jade") 31 | public ModelAndView testJade() { 32 | ModelAndView modelAndView = new ModelAndView("jade"); 33 | modelAndView.add("hello", "hello jade"); 34 | return modelAndView; 35 | } 36 | 37 | @GetMapping("/freemarker") 38 | public ModelAndView testFreeMarker() { 39 | ModelAndView modelAndView = new ModelAndView("freemarker"); 40 | modelAndView.add("test", "hello freemarker"); 41 | return modelAndView; 42 | } 43 | 44 | public static void main(String[] args) throws Exception { 45 | WebApplication.run(Hello.class); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/config/AuthConfig.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.config; 2 | 3 | import cn.bdqfork.context.configuration.Configuration; 4 | import cn.bdqfork.web.route.filter.AuthFilter; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.json.JsonObject; 7 | import io.vertx.ext.auth.AuthProvider; 8 | import io.vertx.ext.auth.shiro.ShiroAuth; 9 | import io.vertx.ext.auth.shiro.ShiroAuthOptions; 10 | import io.vertx.ext.auth.shiro.ShiroAuthRealmType; 11 | import io.vertx.ext.web.handler.AuthHandler; 12 | import io.vertx.ext.web.handler.BasicAuthHandler; 13 | 14 | import javax.inject.Named; 15 | import javax.inject.Singleton; 16 | 17 | /** 18 | * @author bdq 19 | * @since 2020/1/28 20 | */ 21 | @Singleton 22 | @Configuration 23 | public class AuthConfig { 24 | 25 | @Singleton 26 | @Named 27 | public AuthProvider authProvider(Vertx vertx) { 28 | JsonObject config = new JsonObject().put("properties_path", "classpath:vertx-users.properties"); 29 | ShiroAuthOptions options = new ShiroAuthOptions().setType(ShiroAuthRealmType.PROPERTIES).setConfig(config); 30 | return ShiroAuth.create(vertx, options); 31 | } 32 | 33 | @Singleton 34 | @Named 35 | public AuthHandler authHandler(AuthProvider authProvider) { 36 | return BasicAuthHandler.create(authProvider); 37 | } 38 | 39 | @Singleton 40 | @Named 41 | public AuthFilter authFilter() { 42 | AuthFilter authFilter = new AuthFilter(); 43 | authFilter.setDeniedHandler(routingContext -> { 44 | routingContext.response().setStatusCode(403).end("you have not permissions!"); 45 | }); 46 | return authFilter; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/domain/IService.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | import io.reactivex.Flowable; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/26 8 | */ 9 | public interface IService { 10 | Flowable getUserName(String username); 11 | 12 | Flowable testError(String username); 13 | } 14 | -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/domain/ServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | import cn.bdqfork.web.annotation.VerticleMapping; 4 | import io.reactivex.Flowable; 5 | 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2020/1/26 11 | */ 12 | @Singleton 13 | @VerticleMapping("ServiceImpl1") 14 | public class ServiceImpl implements IService { 15 | @Override 16 | public Flowable getUserName(String username) { 17 | return Flowable.just(username); 18 | } 19 | 20 | @Override 21 | public Flowable testError(String username) { 22 | return Flowable.just(username) 23 | .map(s -> 1 / 0).map(i -> null); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/domain/ServiceImpl2.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.domain; 2 | 3 | import cn.bdqfork.web.annotation.VerticleMapping; 4 | import io.reactivex.Flowable; 5 | 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2020/1/26 11 | */ 12 | @Singleton 13 | @VerticleMapping("ServiceImpl2") 14 | public class ServiceImpl2 implements IService { 15 | @Override 16 | public Flowable getUserName(String username) { 17 | return Flowable.just(username); 18 | } 19 | 20 | @Override 21 | public Flowable testError(String username) { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /festival-example/web/src/main/java/cn/bdqfork/kotlin/example/model/User.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.example.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | 5 | import java.util.Date; 6 | 7 | public class User { 8 | 9 | int id; 10 | String username; 11 | boolean active; 12 | @JsonFormat(pattern = "YYYY") 13 | Date createDate; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public User setId(int id) { 20 | this.id = id; 21 | return this; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public User setUsername(String username) { 29 | this.username = username; 30 | return this; 31 | } 32 | 33 | public boolean isActive() { 34 | return active; 35 | } 36 | 37 | public User setActive(boolean active) { 38 | this.active = active; 39 | return this; 40 | } 41 | 42 | public Date getCreateDate() { 43 | return createDate; 44 | } 45 | 46 | public User setCreateDate(Date createDate) { 47 | this.createDate = createDate; 48 | return this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | host: 127.0.0.1 3 | port: 8080 4 | http2: 5 | enable: true 6 | ssl: 7 | enable: false 8 | path: test.jks 9 | password: '123456' 10 | uploads: 11 | limit: 2147483648 12 | static: 13 | enable: true 14 | cache: 15 | enable: true 16 | template: 17 | enable: true 18 | type: thymeleaf 19 | suffix: ".html" -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | hello world! 8 | 9 | 10 | -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/template/freemarker.ftl: -------------------------------------------------------------------------------- 1 | ${hello} -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/template/jade.jade: -------------------------------------------------------------------------------- 1 | div !{hello} -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/template/thymeleaf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Thymeleaf测试页 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/test.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/festival-example/web/src/main/resources/test.jks -------------------------------------------------------------------------------- /festival-example/web/src/main/resources/vertx-users.properties: -------------------------------------------------------------------------------- 1 | user.tim = mypassword,administrator,developer 2 | user.bob = hispassword,developer 3 | user.joe = anotherpassword,manager 4 | role.administrator=* 5 | role.manager=play_golf,say_buzzwords 6 | role.developer=do_actual_work -------------------------------------------------------------------------------- /festival-kotlin-web/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | api "io.vertx:vertx-web:${libs.vertx}" 5 | implementation "io.vertx:vertx-lang-kotlin-coroutines:${libs.vertx}" 6 | 7 | compileOnly "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${libs.jackson}" 8 | compileOnly "io.vertx:vertx-web-templ-freemarker:${libs.vertx}" 9 | compileOnly "io.vertx:vertx-web-templ-thymeleaf:${libs.vertx}" 10 | compileOnly "io.vertx:vertx-web-templ-jade:${libs.vertx}" 11 | compileOnly "joda-time:joda-time:${libs.joda}" 12 | 13 | api project(':festival-context') 14 | } 15 | 16 | publishing { 17 | publications { 18 | mavenJava(MavenPublication) { 19 | pom { 20 | description = 'A kotlin web framework based vertx!' 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/RouterAware.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web 2 | 3 | import cn.bdqfork.core.exception.BeansException 4 | import io.vertx.ext.web.Router 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/2 9 | */ 10 | interface RouterAware { 11 | @Throws(BeansException::class) 12 | fun setRouter(router: Router) 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/VertxAware.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web 2 | 3 | import cn.bdqfork.core.exception.BeansException 4 | import io.vertx.core.Vertx 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/26 9 | */ 10 | interface VertxAware { 11 | @Throws(BeansException::class) 12 | fun setVertx(vertx: Vertx) 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/WebApplication.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/17 6 | */ 7 | class WebApplication { 8 | 9 | companion object { 10 | fun run(clazz: Class<*>) { 11 | val scanPath = clazz.getPackage().name 12 | try { 13 | WebApplicationContext(scanPath).start() 14 | } catch (e: Exception) { 15 | throw IllegalStateException(e) 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/annotation/Auth.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.annotation 2 | 3 | /** 4 | * 该注解应使用在Route上,表示该Route需要进行验证 5 | * 6 | * @author bdq 7 | * @since 2020/1/27 8 | */ 9 | @MustBeDocumented 10 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | annotation class Auth -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/annotation/PermitAll.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/28 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 10 | annotation class PermitAll -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/annotation/PermitAllowed.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.annotation 2 | 3 | import cn.bdqfork.kotlin.web.constant.LogicType 4 | 5 | /** 6 | * 表示哪些权限可以访问api 7 | * 8 | * @author bdq 9 | * @since 2020/1/27 10 | */ 11 | @Auth 12 | @MustBeDocumented 13 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 14 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 15 | annotation class PermitAllowed(vararg val value: String, val logic: LogicType = LogicType.AND) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/annotation/RolesAllowed.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.annotation 2 | 3 | import cn.bdqfork.kotlin.web.constant.LogicType 4 | 5 | /** 6 | * 表示哪些角色可以访问api 7 | * 8 | * @author bdq 9 | * @since 2020/1/27 10 | */ 11 | @Auth 12 | @MustBeDocumented 13 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 14 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 15 | annotation class RolesAllowed(vararg val value: String, val logic: LogicType = LogicType.AND) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/annotation/VerticleMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.annotation 2 | 3 | import javax.inject.Named 4 | import javax.inject.Singleton 5 | 6 | /** 7 | * 该注解用于将服务转化为Verticle,服务之间的调用将通过EventBus进行通信。 8 | * 9 | * @author bdq 10 | * @since 2020/1/21 11 | */ 12 | @Singleton 13 | @Named 14 | @MustBeDocumented 15 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 16 | @Target(AnnotationTarget.CLASS) 17 | annotation class VerticleMapping(val value: String = "") -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/constant/ContentType.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.constant 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/15 6 | */ 7 | object ContentType { 8 | const val CONTENT_TYPE = "Content-Type" 9 | const val PLAIN = "text/plain" 10 | const val HTML = "text/html" 11 | const val XML = "application/xml" 12 | const val JSON = "application/json" 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/constant/LogicType.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.constant 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/28 6 | */ 7 | enum class LogicType { 8 | AND, OR 9 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/ModelAndView.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route 2 | 3 | import java.util.* 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/21 8 | */ 9 | class ModelAndView @JvmOverloads constructor(val view: String, private val model: MutableMap = HashMap()) { 10 | fun add(key: String, value: Any?) { 11 | model[key] = value 12 | } 13 | 14 | fun getModel(): Map { 15 | return model 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/PermitHolder.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route 2 | 3 | import cn.bdqfork.kotlin.web.annotation.PermitAllowed 4 | import cn.bdqfork.kotlin.web.annotation.RolesAllowed 5 | import cn.bdqfork.kotlin.web.constant.LogicType 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/10 10 | */ 11 | class PermitHolder { 12 | var permits: Array 13 | var logicType: LogicType 14 | 15 | constructor(logicType: LogicType, vararg permits: String) { 16 | this.logicType = logicType 17 | this.permits = permits 18 | } 19 | 20 | constructor(permitAllowed: PermitAllowed) { 21 | permits = permitAllowed.value 22 | logicType = permitAllowed.logic 23 | } 24 | 25 | constructor(rolesAllowed: RolesAllowed) { 26 | permits = rolesAllowed.value 27 | logicType = rolesAllowed.logic 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/RouteHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route 2 | 3 | import cn.bdqfork.core.util.ReflectUtils 4 | import cn.bdqfork.kotlin.web.constant.ContentType 5 | import cn.bdqfork.kotlin.web.route.message.HttpMessageHandler 6 | import cn.bdqfork.kotlin.web.route.response.ResponseHandlerFactory 7 | import io.vertx.core.Handler 8 | import io.vertx.ext.web.RoutingContext 9 | import java.lang.reflect.Method 10 | 11 | /** 12 | * @author bdq 13 | * @since 2020/2/18 14 | */ 15 | class RouteHandler(private val httpMessageHandler: HttpMessageHandler, private val responseHandlerFactory: ResponseHandlerFactory, private val method: Method, private val bean: Any) : Handler { 16 | override fun handle(routingContext: RoutingContext) { 17 | try { 18 | val args = httpMessageHandler.handle(routingContext, method.parameters) 19 | val result = ReflectUtils.invokeMethod(bean, method, *args) 20 | if (ReflectUtils.isReturnVoid(method)) { 21 | return 22 | } 23 | var contentType = routingContext.acceptableContentType 24 | if (result is ModelAndView) { 25 | contentType = ContentType.HTML 26 | } 27 | responseHandlerFactory.getResponseHandler(contentType).handle(routingContext, result) 28 | } catch (e: Exception) { 29 | throw IllegalStateException(e) 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/Consumes.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * 指定路由的consumes 5 | * 6 | * @author bdq 7 | * @since 2020/2/12 8 | */ 9 | @MustBeDocumented 10 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.FUNCTION) 12 | annotation class Consumes(vararg val value: String) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/DeleteMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import io.vertx.core.http.HttpMethod 4 | import io.vertx.ext.web.handler.TimeoutHandler 5 | 6 | /** 7 | * 用于DELETE请求 8 | * 9 | * @author bdq 10 | * @since 2020/1/21 11 | */ 12 | @RouteMapping(method = HttpMethod.DELETE) 13 | @MustBeDocumented 14 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 15 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 16 | annotation class DeleteMapping(val value: String, val timeout: Long = TimeoutHandler.DEFAULT_TIMEOUT) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/GetMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import io.vertx.core.http.HttpMethod 4 | 5 | /** 6 | * 用于GET请求 7 | * 8 | * @author bdq 9 | * @since 2020/1/21 10 | */ 11 | @RouteMapping(method = HttpMethod.GET) 12 | @MustBeDocumented 13 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 14 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 15 | annotation class GetMapping(val value: String, val timeout: Long = -1) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/OnActive.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/19 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.FUNCTION) 10 | annotation class OnActive -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/OnClose.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/19 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.FUNCTION) 10 | annotation class OnClose -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/OnOpen.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/19 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.FUNCTION) 10 | annotation class OnOpen -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/Param.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * 该注解用于方法参数,该注解修饰的参数表示需要注入的参数 5 | * 6 | * @author bdq 7 | * @since 2020/2/1 8 | */ 9 | @MustBeDocumented 10 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.ANNOTATION_CLASS) 12 | annotation class Param( 13 | /** 14 | * 参数名 15 | */ 16 | val value: String, 17 | /** 18 | * 是否必须参数 19 | */ 20 | val required: Boolean = true, 21 | /** 22 | * 默认值 23 | */ 24 | val defaultValue: String = "null") -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/PostMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import io.vertx.core.http.HttpMethod 4 | import io.vertx.ext.web.handler.TimeoutHandler 5 | 6 | /** 7 | * 用于POST请求 8 | * 9 | * @author bdq 10 | * @since 2020/1/21 11 | */ 12 | @RouteMapping(method = HttpMethod.POST) 13 | @MustBeDocumented 14 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 15 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) 16 | annotation class PostMapping(val value: String, val timeout: Long = TimeoutHandler.DEFAULT_TIMEOUT) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/Produces.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * 指定路由的produces 5 | * 6 | * @author bdq 7 | * @since 2020/2/12 8 | */ 9 | @MustBeDocumented 10 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.FUNCTION) 12 | annotation class Produces(vararg val value: String) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/PutMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import io.vertx.core.http.HttpMethod 4 | import io.vertx.ext.web.handler.TimeoutHandler 5 | 6 | /** 7 | * 用于PUT请求 8 | * 9 | * @author bdq 10 | * @since 2020/1/21 11 | */ 12 | @RouteMapping(method = HttpMethod.PUT) 13 | @MustBeDocumented 14 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 15 | @Target(AnnotationTarget.FUNCTION) 16 | annotation class PutMapping(val value: String, val timeout: Long = TimeoutHandler.DEFAULT_TIMEOUT) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/RequestBody.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/13 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.VALUE_PARAMETER) 10 | annotation class RequestBody -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/RouteController.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import cn.bdqfork.core.annotation.Optimize 4 | import javax.inject.Named 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/29 9 | */ 10 | @Optimize 11 | @Named 12 | @RouteMapping 13 | @MustBeDocumented 14 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 15 | @Target(AnnotationTarget.CLASS) 16 | annotation class RouteController(val value: String = "") -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/RouteMapping.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | import io.vertx.core.http.HttpMethod 4 | import io.vertx.ext.web.handler.TimeoutHandler 5 | 6 | /** 7 | * 用于将url请求映射到方法 8 | * 9 | * @author bdq 10 | * @since 2020/1/21 11 | */ 12 | @MustBeDocumented 13 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 14 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 15 | annotation class RouteMapping(val value: String = "", val method: HttpMethod = HttpMethod.OPTIONS, val timeout: Long = TimeoutHandler.DEFAULT_TIMEOUT) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/annotation/ServerEndpoint.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.annotation 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/19 6 | */ 7 | @MustBeDocumented 8 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.CLASS) 10 | annotation class ServerEndpoint(val value: String) -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/filter/Filter.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.filter 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/28 8 | */ 9 | @FunctionalInterface 10 | interface Filter { 11 | @Throws(Exception::class) 12 | fun doFilter(routingContext: RoutingContext, filterChain: FilterChain) 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/filter/FilterChain.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.filter 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | import java.util.* 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/28 9 | */ 10 | class FilterChain(filters: List) : Filter { 11 | private val filters: MutableList = ArrayList() 12 | private var index = 0 13 | 14 | init { 15 | this.filters.addAll(filters) 16 | } 17 | 18 | fun registerFilter(filter: Filter) { 19 | filters.add(filter) 20 | } 21 | 22 | @Throws(Exception::class) 23 | fun doFilter(routingContext: RoutingContext) { 24 | doFilter(routingContext, this) 25 | } 26 | 27 | @Throws(Exception::class) 28 | override fun doFilter(routingContext: RoutingContext, filterChain: FilterChain) { 29 | if (index == filters.size) { 30 | return 31 | } 32 | filters[index++].doFilter(routingContext, filterChain) 33 | } 34 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/filter/FilterChainFactory.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.filter 2 | 3 | import java.util.* 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/13 8 | */ 9 | class FilterChainFactory { 10 | private val filters: MutableList = LinkedList() 11 | 12 | fun registerFilter(filter: Filter) { 13 | filters.add(filter) 14 | } 15 | 16 | fun registerFilters(filters: Collection) { 17 | this.filters.addAll(filters) 18 | } 19 | 20 | fun getFilterChain(target: Filter): FilterChain { 21 | val filterChain = FilterChain(filters) 22 | filterChain.registerFilter(target) 23 | return filterChain 24 | } 25 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/AbstractHttpMessageHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message 2 | 3 | import io.vertx.core.http.HttpMethod 4 | import io.vertx.ext.web.RoutingContext 5 | import java.lang.reflect.Parameter 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/31 10 | */ 11 | abstract class AbstractHttpMessageHandler : HttpMessageHandler { 12 | override fun handle(routingContext: RoutingContext, parameters: Array): Array { 13 | val httpServerRequest = routingContext.request() 14 | val httpMethod = httpServerRequest.method() 15 | return if (httpMethod == HttpMethod.GET || httpMethod == HttpMethod.POST || httpMethod == HttpMethod.PUT || httpMethod == HttpMethod.DELETE) { 16 | doHandle(routingContext, parameters) 17 | } else arrayOfNulls(0) 18 | } 19 | 20 | protected abstract fun doHandle(routingContext: RoutingContext, parameters: Array): Array 21 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/DefaultHttpMessageHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message 2 | 3 | import cn.bdqfork.kotlin.web.route.message.resolver.ParameterResolver 4 | import cn.bdqfork.kotlin.web.route.message.resolver.ParameterResolverFactory 5 | import io.vertx.ext.web.RoutingContext 6 | import java.lang.reflect.Parameter 7 | import java.util.* 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/1/31 12 | */ 13 | class DefaultHttpMessageHandler(parameterResolverFactory: ParameterResolverFactory) : AbstractHttpMessageHandler() { 14 | private val parameterResolver: ParameterResolver = parameterResolverFactory.createResolverChain() 15 | override fun doHandle(routingContext: RoutingContext, parameters: Array): Array { 16 | val args: MutableList = ArrayList(parameters.size) 17 | for (parameter in parameters) { 18 | val value = parameterResolver.resolve(parameter, routingContext) 19 | args.add(value) 20 | } 21 | return args.toTypedArray() 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/HttpMessageHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | import java.lang.reflect.Parameter 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/31 9 | */ 10 | interface HttpMessageHandler { 11 | @Throws(Exception::class) 12 | fun handle(routingContext: RoutingContext, parameters: Array): Array 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/resolver/AbstractParameterResolver.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message.resolver 2 | 3 | import io.vertx.core.MultiMap 4 | import io.vertx.core.http.HttpMethod 5 | import io.vertx.ext.web.RoutingContext 6 | import java.lang.reflect.Parameter 7 | 8 | /** 9 | * @author bdq 10 | * @since 2020/2/11 11 | */ 12 | abstract class AbstractParameterResolver : ParameterResolver { 13 | private var next: AbstractParameterResolver? = null 14 | 15 | fun setNext(next: AbstractParameterResolver?) { 16 | this.next = next 17 | } 18 | 19 | @Throws(Exception::class) 20 | override fun resolve(parameter: Parameter, routingContext: RoutingContext): Any? { 21 | if (resolvable(parameter,routingContext)) { 22 | return doResolve(parameter, routingContext) 23 | } 24 | return if (next != null) { 25 | next!!.resolve(parameter, routingContext) 26 | } else null 27 | } 28 | 29 | @Throws(Exception::class) 30 | protected abstract fun doResolve(parameter: Parameter, routingContext: RoutingContext): Any? 31 | protected abstract fun resolvable(parameter: Parameter,routingContext: RoutingContext): Boolean 32 | 33 | protected fun resolveParams(routingContext: RoutingContext): MultiMap { 34 | val pathParams = routingContext.pathParams() 35 | return if (routingContext.request().method() == HttpMethod.GET) { 36 | routingContext.queryParams().addAll(pathParams) 37 | } else { 38 | val httpServerRequest = routingContext.request() 39 | httpServerRequest.formAttributes().addAll(pathParams) 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/resolver/JsonBodyParameterResolver.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message.resolver 2 | 3 | import cn.bdqfork.core.util.AnnotationUtils 4 | import cn.bdqfork.kotlin.web.constant.ContentType 5 | import cn.bdqfork.kotlin.web.route.annotation.RequestBody 6 | import io.vertx.core.json.Json 7 | import io.vertx.core.json.JsonArray 8 | import io.vertx.core.json.JsonObject 9 | import io.vertx.ext.web.RoutingContext 10 | import java.lang.reflect.Parameter 11 | 12 | /** 13 | * @author bdq 14 | * @since 2020/2/13 15 | */ 16 | class JsonBodyParameterResolver : AbstractParameterResolver() { 17 | @Throws(Exception::class) 18 | override fun doResolve(parameter: Parameter, routingContext: RoutingContext): Any? { 19 | val parameterType = parameter.type 20 | if (parameterType == JsonObject::class.java) { 21 | return routingContext.bodyAsJson 22 | } 23 | if (parameterType == JsonArray::class.java) { 24 | return routingContext.bodyAsJsonArray 25 | } 26 | if (parameterType == String::class.java) { 27 | return routingContext.bodyAsString 28 | } 29 | val buffer = routingContext.body 30 | return Json.decodeValue(buffer, parameterType) 31 | } 32 | 33 | override fun resolvable(parameter: Parameter, routingContext: RoutingContext): Boolean { 34 | val contentType = routingContext.request().getHeader(ContentType.CONTENT_TYPE) 35 | return AnnotationUtils.isAnnotationPresent(parameter, RequestBody::class.java) 36 | && ContentType.CONTENT_TYPE == contentType 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/resolver/ParameterResolver.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message.resolver 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | import java.lang.reflect.Parameter 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/11 9 | */ 10 | interface ParameterResolver { 11 | @Throws(Exception::class) 12 | fun resolve(parameter: Parameter, routingContext: RoutingContext): Any? 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/resolver/ParameterResolverFactory.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message.resolver 2 | 3 | import java.util.* 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/13 8 | */ 9 | class ParameterResolverFactory { 10 | private val parameterResolvers: MutableList = ArrayList() 11 | private fun registerResolver(parameterResolver: AbstractParameterResolver) { 12 | parameterResolvers.add(parameterResolver) 13 | } 14 | 15 | fun registerResolver(parameterResolvers: Collection) { 16 | this.parameterResolvers.addAll(parameterResolvers) 17 | } 18 | 19 | fun createResolverChain(): ParameterResolver { 20 | for (i in 0 until parameterResolvers.size - 1) { 21 | val resolver = parameterResolvers[i] 22 | val next = parameterResolvers[i + 1] 23 | resolver.setNext(next) 24 | } 25 | return parameterResolvers[0] 26 | } 27 | 28 | init { 29 | registerResolver(ContextParameterResolver()) 30 | registerResolver(PrimitiveParameterResolver()) 31 | registerResolver(JsonBodyParameterResolver()) 32 | registerResolver(XmlBodyParameterResolver()) 33 | registerResolver(DateParameterResolver()) 34 | } 35 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/message/resolver/XmlBodyParameterResolver.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.message.resolver 2 | 3 | import cn.bdqfork.core.util.AnnotationUtils 4 | import cn.bdqfork.kotlin.web.constant.ContentType 5 | import cn.bdqfork.kotlin.web.route.annotation.RequestBody 6 | import cn.bdqfork.kotlin.web.util.XmlUtils.fromXml 7 | import io.vertx.ext.web.RoutingContext 8 | import java.lang.reflect.Parameter 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/2/20 13 | */ 14 | class XmlBodyParameterResolver : AbstractParameterResolver() { 15 | @Throws(Exception::class) 16 | override fun doResolve(parameter: Parameter, routingContext: RoutingContext): Any? { 17 | val parameterType = parameter.type 18 | if (parameterType == String::class.java) { 19 | return routingContext.bodyAsString 20 | } 21 | val xml = routingContext.bodyAsString 22 | return fromXml(xml, parameterType) 23 | } 24 | 25 | override fun resolvable(parameter: Parameter, routingContext: RoutingContext): Boolean { 26 | val contentType = routingContext.request().getHeader(ContentType.CONTENT_TYPE) 27 | return AnnotationUtils.isAnnotationPresent(parameter, RequestBody::class.java) 28 | && ContentType.XML == contentType 29 | } 30 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/AbstractResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/12 8 | */ 9 | abstract class AbstractResponseHandler : ResponseHandleStrategy { 10 | @Throws(Exception::class) 11 | override fun handle(routingContext: RoutingContext, result: Any?) { 12 | if (result == null) { 13 | routingContext.response().end() 14 | } 15 | doHandle(routingContext, result!!) 16 | } 17 | 18 | @Throws(Exception::class) 19 | protected abstract fun doHandle(routingContext: RoutingContext, result: Any) 20 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/HtmlResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import cn.bdqfork.kotlin.web.route.ModelAndView 4 | import cn.bdqfork.kotlin.web.route.TemplateManager 5 | import io.vertx.core.buffer.Buffer 6 | import io.vertx.ext.web.RoutingContext 7 | import io.vertx.kotlin.coroutines.awaitResult 8 | import kotlinx.coroutines.runBlocking 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/2/21 13 | */ 14 | class HtmlResponseHandler(private val templateManager: TemplateManager) : AbstractResponseHandler() { 15 | @Throws(Exception::class) 16 | override fun doHandle(routingContext: RoutingContext, result: Any) = runBlocking { 17 | val response = routingContext.response() 18 | if (templateManager.isEnable) { 19 | val modelAndView = result as ModelAndView 20 | val template = templateManager.templatePath + "/" + modelAndView.view + templateManager.suffix 21 | val buffer = awaitResult { h -> templateManager.templateEngine.render(modelAndView.getModel(), template, h) } 22 | response.end(buffer) 23 | } else { 24 | routingContext.fail(500, IllegalStateException("template is not enabled!")) 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/JsonResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import io.vertx.core.json.Json 4 | import io.vertx.ext.web.RoutingContext 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/12 9 | */ 10 | class JsonResponseHandler : AbstractResponseHandler() { 11 | @Throws(Exception::class) 12 | override fun doHandle(routingContext: RoutingContext, result: Any) { 13 | routingContext.response().end(Json.encodePrettily(result)) 14 | } 15 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/ResponseHandleStrategy.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/30 8 | */ 9 | interface ResponseHandleStrategy { 10 | @Throws(Exception::class) 11 | fun handle(routingContext: RoutingContext, result: Any?) 12 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/ResponseHandlerFactory.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import cn.bdqfork.core.util.StringUtils 4 | import cn.bdqfork.kotlin.web.constant.ContentType 5 | import java.util.concurrent.ConcurrentHashMap 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/15 10 | */ 11 | open class ResponseHandlerFactory { 12 | open val responseHandlerMap: MutableMap = ConcurrentHashMap(16) 13 | 14 | fun registerResponseHandler(contentType: String, responseHandleStrategy: ResponseHandleStrategy) { 15 | responseHandlerMap[contentType] = responseHandleStrategy 16 | } 17 | 18 | fun getResponseHandler(contentType: String?): ResponseHandleStrategy { 19 | if (StringUtils.isEmpty(contentType) || !responseHandlerMap.containsKey(contentType)) { 20 | return responseHandlerMap[ContentType.JSON]!! 21 | } 22 | return responseHandlerMap[contentType]!! 23 | } 24 | 25 | init { 26 | registerResponseHandler(ContentType.PLAIN, TextPlainResponseHandler()) 27 | registerResponseHandler(ContentType.JSON, JsonResponseHandler()) 28 | registerResponseHandler(ContentType.XML, XmlResponseHandler()) 29 | } 30 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/TextPlainResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import io.vertx.ext.web.RoutingContext 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/12 8 | */ 9 | class TextPlainResponseHandler : AbstractResponseHandler() { 10 | @Throws(Exception::class) 11 | override fun doHandle(routingContext: RoutingContext, result: Any) { 12 | routingContext.response().end(result.toString()) 13 | } 14 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/route/response/XmlResponseHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.route.response 2 | 3 | import cn.bdqfork.kotlin.web.util.XmlUtils 4 | import io.vertx.ext.web.RoutingContext 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/20 9 | */ 10 | class XmlResponseHandler : AbstractResponseHandler() { 11 | @Throws(Exception::class) 12 | override fun doHandle(routingContext: RoutingContext, result: Any) { 13 | routingContext.response().end(XmlUtils.toXml(result)) 14 | } 15 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/server/WebServer.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.server 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/12 6 | */ 7 | interface WebServer { 8 | @Throws(Exception::class) 9 | fun start() 10 | 11 | @Throws(Exception::class) 12 | fun stop() 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/server/WebVerticle.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.server 2 | 3 | import io.vertx.kotlin.coroutines.CoroutineVerticle 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/21 8 | */ 9 | class WebVerticle(private val webServer: WebServer) : CoroutineVerticle() { 10 | 11 | override suspend fun start() { 12 | webServer.start() 13 | } 14 | 15 | override suspend fun stop() { 16 | webServer.stop() 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/service/JsonMessageCodec.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.service 2 | 3 | import io.vertx.core.buffer.Buffer 4 | import io.vertx.core.eventbus.MessageCodec 5 | import io.vertx.core.json.Json 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/26 10 | */ 11 | class JsonMessageCodec : MessageCodec { 12 | override fun encodeToWire(buffer: Buffer, o: Any?) { 13 | buffer.appendBuffer(Json.encodeToBuffer(o)) 14 | } 15 | 16 | override fun decodeFromWire(pos: Int, buffer: Buffer): Any? { 17 | return Json.decodeValue(buffer) 18 | } 19 | 20 | override fun transform(o: Any?): Any? { 21 | return o 22 | } 23 | 24 | override fun name(): String { 25 | return NAME 26 | } 27 | 28 | override fun systemCodecID(): Byte { 29 | return -1 30 | } 31 | 32 | companion object { 33 | const val NAME = "json" 34 | } 35 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/service/MethodInvocation.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.service 2 | 3 | import java.io.Serializable 4 | import java.lang.reflect.Method 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/26 9 | */ 10 | class MethodInvocation(method: Method, var arguments: Array) : Serializable { 11 | var methodName: String = method.name 12 | var argumentClasses: Array> = method.parameterTypes 13 | 14 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/service/VerticleProxyHandler.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.service 2 | 3 | import cn.bdqfork.kotlin.web.util.EventBusUtils 4 | import io.vertx.core.Vertx 5 | import io.vertx.core.eventbus.DeliveryOptions 6 | import io.vertx.core.eventbus.Message 7 | import io.vertx.kotlin.coroutines.awaitResult 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.async 10 | import kotlinx.coroutines.runBlocking 11 | import java.lang.reflect.InvocationHandler 12 | import java.lang.reflect.Method 13 | 14 | /** 15 | * @author bdq 16 | * @since 2020/1/26 17 | */ 18 | class VerticleProxyHandler(private val vertx: Vertx, private val targetClass: Class<*>) : InvocationHandler { 19 | private val options: DeliveryOptions = DeliveryOptions() 20 | @Throws(Throwable::class) 21 | override fun invoke(proxy: Any, method: Method, args: Array?): Any? = runBlocking { 22 | val methodInvocation = MethodInvocation(method, args ?: emptyArray()) 23 | val address = EventBusUtils.getAddress(targetClass) 24 | return@runBlocking GlobalScope.async { 25 | val message = awaitResult> { h -> vertx.eventBus().request(address, methodInvocation, options, h) } 26 | val result = message.body() 27 | if (result is Throwable) { 28 | throw result 29 | } 30 | return@async result 31 | }.await() 32 | } 33 | 34 | init { 35 | options.codecName = JsonMessageCodec.NAME 36 | } 37 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/util/EventBusUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.util 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/26 6 | */ 7 | object EventBusUtils { 8 | fun getAddress(clazz: Class<*>): String { 9 | return clazz.canonicalName 10 | } 11 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/util/SecurityUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.util 2 | 3 | import cn.bdqfork.kotlin.web.constant.LogicType 4 | import io.vertx.ext.auth.User 5 | import io.vertx.kotlin.coroutines.awaitResult 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.async 8 | import kotlinx.coroutines.runBlocking 9 | 10 | /** 11 | * @author bdq 12 | * @since 2020/1/28 13 | */ 14 | object SecurityUtils { 15 | @JvmStatic 16 | fun isPermited(user: User, permits: Array, logicType: LogicType): Boolean = runBlocking { 17 | return@runBlocking GlobalScope.async { 18 | var finalResult = awaitResult { h -> user.isAuthorized(permits[0], h) } 19 | for (i in 1 until permits.size) { 20 | val result = awaitResult { h -> user.isAuthorized(permits[i], h) } 21 | if (logicType == LogicType.AND) { 22 | finalResult = finalResult && result 23 | } 24 | if (logicType == LogicType.OR) { 25 | finalResult = finalResult || result 26 | } 27 | } 28 | return@async finalResult 29 | }.await() 30 | } 31 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/util/VertxUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.util 2 | 3 | import io.vertx.core.Vertx 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/21 8 | */ 9 | object VertxUtils { 10 | @JvmStatic 11 | var vertx: Vertx = Vertx.vertx() 12 | 13 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/kotlin/cn/bdqfork/kotlin/web/util/XmlUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.kotlin.web.util 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException 4 | import com.fasterxml.jackson.dataformat.xml.XmlMapper 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/20 9 | */ 10 | object XmlUtils { 11 | private val xmlMapper = XmlMapper() 12 | @Throws(JsonProcessingException::class) 13 | fun toXml(instance: Any): String { 14 | return xmlMapper.writeValueAsString(instance) 15 | } 16 | 17 | @Throws(JsonProcessingException::class) 18 | fun fromXml(xml: String, clazz: Class): T { 19 | return xmlMapper.readValue(xml, clazz) 20 | } 21 | } -------------------------------------------------------------------------------- /festival-kotlin-web/src/main/resources/META-INF/extensions/cn.bdqfork.context.processor.LifeCycleProcessor: -------------------------------------------------------------------------------- 1 | web=cn.bdqfork.kotlin.web.processor.WebLifeCycleProcessor -------------------------------------------------------------------------------- /festival-web/build.gradle: -------------------------------------------------------------------------------- 1 | def libs = rootProject.ext.libraries 2 | 3 | dependencies { 4 | compileOnly "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${libs.jackson}" 5 | compileOnly "io.vertx:vertx-web-templ-freemarker:${libs.vertx}" 6 | compileOnly "io.vertx:vertx-web-templ-thymeleaf:${libs.vertx}" 7 | compileOnly "io.vertx:vertx-web-templ-jade:${libs.vertx}" 8 | compileOnly "joda-time:joda-time:${libs.joda}" 9 | 10 | api "io.vertx:vertx-web:${libs.vertx}" 11 | api "io.vertx:vertx-rx-java2:${libs.vertx}" 12 | api project(':festival-context') 13 | } 14 | 15 | publishing { 16 | publications { 17 | mavenJava(MavenPublication) { 18 | pom { 19 | description = 'A web framework based vertx!' 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/RouterAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import io.vertx.ext.web.Router; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/2 9 | */ 10 | public interface RouterAware { 11 | void setRouter(Router router) throws BeansException; 12 | } 13 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/VertxAware.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import io.vertx.core.Vertx; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/26 9 | */ 10 | public interface VertxAware { 11 | void setVertx(Vertx vertx) throws BeansException; 12 | } 13 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/WebApplication.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/17 6 | */ 7 | public class WebApplication { 8 | public static void run(Class clazz) { 9 | String scanPath = clazz.getPackage().getName(); 10 | try { 11 | new WebApplicationContext(scanPath).start(); 12 | } catch (Exception e) { 13 | throw new IllegalStateException(e); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/annotation/Auth.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 该注解应使用在Route上,表示该Route需要进行验证 7 | * 8 | * @author bdq 9 | * @since 2020/1/27 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 14 | public @interface Auth { 15 | } 16 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/annotation/PermitAll.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/1/28 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ElementType.TYPE, ElementType.METHOD}) 12 | public @interface PermitAll { 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/annotation/PermitAllowed.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.annotation; 2 | 3 | import cn.bdqfork.web.constant.LogicType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 表示哪些权限可以访问api 9 | * 10 | * @author bdq 11 | * @since 2020/1/27 12 | */ 13 | @Auth 14 | @Documented 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.METHOD}) 17 | public @interface PermitAllowed { 18 | String[] value(); 19 | 20 | LogicType logic() default LogicType.AND; 21 | } 22 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/annotation/RolesAllowed.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.annotation; 2 | 3 | import cn.bdqfork.web.constant.LogicType; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 表示哪些角色可以访问api 9 | * 10 | * @author bdq 11 | * @since 2020/1/27 12 | */ 13 | @Auth 14 | @Documented 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.METHOD}) 17 | public @interface RolesAllowed { 18 | String[] value(); 19 | 20 | LogicType logic() default LogicType.AND; 21 | } 22 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/annotation/VerticleMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.annotation; 2 | 3 | import javax.inject.Named; 4 | import javax.inject.Singleton; 5 | import java.lang.annotation.Documented; 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 11 | 12 | /** 13 | * 该注解用于将服务转化为Verticle,服务之间的调用将通过EventBus进行通信。 14 | * 15 | * @author bdq 16 | * @since 2020/1/21 17 | */ 18 | @Singleton 19 | @Named 20 | @Documented 21 | @Retention(RUNTIME) 22 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE}) 23 | public @interface VerticleMapping { 24 | String value() default ""; 25 | } 26 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/constant/ContentType.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.constant; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/15 6 | */ 7 | public class ContentType { 8 | public static final String CONTENT_TYPE = "Content-Type"; 9 | 10 | public static final String PLAIN = "text/plain"; 11 | public static final String HTML = "text/html"; 12 | 13 | public static final String XML = "application/xml"; 14 | public static final String JSON = "application/json"; 15 | } 16 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/constant/LogicType.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.constant; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/28 6 | */ 7 | public enum LogicType { 8 | AND, OR 9 | } 10 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/ModelAndView.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/21 9 | */ 10 | public class ModelAndView { 11 | private String view; 12 | private Map model; 13 | 14 | public ModelAndView(String view) { 15 | this(view, new HashMap<>()); 16 | } 17 | 18 | public ModelAndView(String view, Map model) { 19 | this.view = view; 20 | this.model = model; 21 | } 22 | 23 | public void add(String key, Object value) { 24 | model.put(key, value); 25 | } 26 | 27 | public String getView() { 28 | return view; 29 | } 30 | 31 | public Map getModel() { 32 | return model; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/PermitHolder.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route; 2 | 3 | import cn.bdqfork.web.annotation.PermitAllowed; 4 | import cn.bdqfork.web.annotation.RolesAllowed; 5 | import cn.bdqfork.web.constant.LogicType; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/10 10 | */ 11 | public class PermitHolder { 12 | private String[] permits; 13 | private LogicType logicType; 14 | 15 | public PermitHolder(LogicType logicType, String... permits) { 16 | this.logicType = logicType; 17 | this.permits = permits; 18 | } 19 | 20 | public PermitHolder(PermitAllowed permitAllowed) { 21 | permits = permitAllowed.value(); 22 | logicType = permitAllowed.logic(); 23 | } 24 | 25 | public PermitHolder(RolesAllowed rolesAllowed) { 26 | permits = rolesAllowed.value(); 27 | logicType = rolesAllowed.logic(); 28 | } 29 | 30 | public String[] getPermits() { 31 | return permits; 32 | } 33 | 34 | public LogicType getLogicType() { 35 | return logicType; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/Consumes.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 指定路由的consumes 7 | * 8 | * @author bdq 9 | * @since 2020/2/12 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.METHOD) 14 | public @interface Consumes { 15 | String[] value(); 16 | } 17 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/DeleteMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | import io.vertx.ext.web.handler.TimeoutHandler; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * 用于DELETE请求 15 | * 16 | * @author bdq 17 | * @since 2020/1/21 18 | */ 19 | @RouteMapping(method = HttpMethod.DELETE) 20 | @Documented 21 | @Retention(RUNTIME) 22 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 23 | public @interface DeleteMapping { 24 | String value(); 25 | 26 | long timeout() default TimeoutHandler.DEFAULT_TIMEOUT; 27 | } 28 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/GetMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | 5 | import java.lang.annotation.Documented; 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 11 | 12 | /** 13 | * 用于GET请求 14 | * 15 | * @author bdq 16 | * @since 2020/1/21 17 | */ 18 | @RouteMapping(method = HttpMethod.GET) 19 | @Documented 20 | @Retention(RUNTIME) 21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 22 | public @interface GetMapping { 23 | String value(); 24 | 25 | long timeout() default -1; 26 | } 27 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/OnActive.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/19 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.METHOD) 12 | public @interface OnActive { 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/OnClose.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/19 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.METHOD) 12 | public @interface OnClose { 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/OnOpen.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/19 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.METHOD) 12 | public @interface OnOpen { 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/Param.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 该注解用于方法参数,该注解修饰的参数表示需要注入的参数 7 | * 8 | * @author bdq 9 | * @since 2020/2/1 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) 14 | public @interface Param { 15 | /** 16 | * 参数名 17 | */ 18 | String value(); 19 | 20 | /** 21 | * 是否必须参数 22 | */ 23 | boolean required() default true; 24 | 25 | /** 26 | * 默认值 27 | */ 28 | String defaultValue() default "null"; 29 | } 30 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/PostMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | import io.vertx.ext.web.handler.TimeoutHandler; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * 用于POST请求 15 | * 16 | * @author bdq 17 | * @since 2020/1/21 18 | */ 19 | @RouteMapping(method = HttpMethod.POST) 20 | @Documented 21 | @Retention(RUNTIME) 22 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 23 | public @interface PostMapping { 24 | String value(); 25 | 26 | long timeout() default TimeoutHandler.DEFAULT_TIMEOUT; 27 | } 28 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/Produces.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 指定路由的produces 7 | * 8 | * @author bdq 9 | * @since 2020/2/12 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.METHOD) 14 | public @interface Produces { 15 | String[] value(); 16 | } 17 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/PutMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | import io.vertx.ext.web.handler.TimeoutHandler; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 12 | 13 | /** 14 | * 用于PUT请求 15 | * 16 | * @author bdq 17 | * @since 2020/1/21 18 | */ 19 | @RouteMapping(method = HttpMethod.PUT) 20 | @Documented 21 | @Retention(RUNTIME) 22 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 23 | public @interface PutMapping { 24 | String value(); 25 | 26 | long timeout() default TimeoutHandler.DEFAULT_TIMEOUT; 27 | } 28 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/RequestBody.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/13 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.PARAMETER) 12 | public @interface RequestBody { 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/RouteController.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | 4 | import cn.bdqfork.core.annotation.Optimize; 5 | 6 | import javax.inject.Named; 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/1/29 12 | */ 13 | @Optimize 14 | @Named 15 | @RouteMapping 16 | @Documented 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 19 | public @interface RouteController { 20 | String value() default ""; 21 | } 22 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/RouteMapping.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | import io.vertx.ext.web.handler.TimeoutHandler; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * 用于将url请求映射到方法 10 | * 11 | * @author bdq 12 | * @since 2020/1/21 13 | */ 14 | @Documented 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD}) 17 | public @interface RouteMapping { 18 | String value() default ""; 19 | 20 | HttpMethod method() default HttpMethod.OPTIONS; 21 | 22 | long timeout() default TimeoutHandler.DEFAULT_TIMEOUT; 23 | } 24 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/annotation/ServerEndpoint.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author bdq 7 | * @since 2020/2/19 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | public @interface ServerEndpoint { 13 | String value(); 14 | } 15 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/filter/Filter.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.filter; 2 | 3 | 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/28 9 | */ 10 | @FunctionalInterface 11 | public interface Filter { 12 | 13 | void doFilter(RoutingContext routingContext, FilterChain filterChain) throws Exception; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/filter/FilterChain.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.filter; 2 | 3 | 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/1/28 12 | */ 13 | public class FilterChain implements Filter { 14 | private List filters = new ArrayList<>(); 15 | private int index = 0; 16 | 17 | public FilterChain() { 18 | } 19 | 20 | public FilterChain(List filters) { 21 | this.filters.addAll(filters); 22 | } 23 | 24 | public void registerFilter(Filter filter) { 25 | filters.add(filter); 26 | } 27 | 28 | public void doFilter(RoutingContext routingContext) throws Exception { 29 | doFilter(routingContext, this); 30 | } 31 | 32 | @Override 33 | public void doFilter(RoutingContext routingContext, FilterChain filterChain) throws Exception { 34 | if (index == filters.size()) { 35 | return; 36 | } 37 | filters.get(index++).doFilter(routingContext, filterChain); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/filter/FilterChainFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/13 10 | */ 11 | public class FilterChainFactory { 12 | private final List filters = new LinkedList<>(); 13 | 14 | public void registerFilter(Filter filter) { 15 | filters.add(filter); 16 | } 17 | 18 | public void registerFilters(Collection filters) { 19 | this.filters.addAll(filters); 20 | } 21 | 22 | public FilterChain getFilterChain(Filter target) { 23 | FilterChain filterChain = new FilterChain(filters); 24 | filterChain.registerFilter(target); 25 | return filterChain; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/AbstractHttpMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message; 2 | 3 | import io.vertx.core.http.HttpMethod; 4 | import io.vertx.core.http.HttpServerRequest; 5 | import io.vertx.ext.web.RoutingContext; 6 | 7 | import java.lang.reflect.Parameter; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/1/31 12 | */ 13 | public abstract class AbstractHttpMessageHandler implements HttpMessageHandler { 14 | @Override 15 | public Object[] handle(RoutingContext routingContext, Parameter[] parameters) throws Exception { 16 | HttpServerRequest httpServerRequest = routingContext.request(); 17 | HttpMethod httpMethod = httpServerRequest.method(); 18 | if (httpMethod == HttpMethod.GET || httpMethod == HttpMethod.POST 19 | || httpMethod == HttpMethod.PUT || httpMethod == HttpMethod.DELETE) { 20 | return doHandle(routingContext, parameters); 21 | } 22 | return new Object[0]; 23 | } 24 | 25 | protected abstract Object[] doHandle(RoutingContext routingContext, Parameter[] parameters) throws Exception; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/DefaultHttpMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message; 2 | 3 | import cn.bdqfork.web.route.message.resolver.ParameterResolver; 4 | import cn.bdqfork.web.route.message.resolver.ParameterResolverFactory; 5 | import io.vertx.ext.web.RoutingContext; 6 | 7 | import java.lang.reflect.Parameter; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author bdq 13 | * @since 2020/1/31 14 | */ 15 | public class DefaultHttpMessageHandler extends AbstractHttpMessageHandler { 16 | private ParameterResolver parameterResolver; 17 | 18 | public DefaultHttpMessageHandler(ParameterResolverFactory parameterResolverFactory) { 19 | this.parameterResolver = parameterResolverFactory.createResolverChain(); 20 | } 21 | 22 | @Override 23 | protected Object[] doHandle(RoutingContext routingContext, Parameter[] parameters) throws Exception { 24 | 25 | List args = new ArrayList<>(parameters.length); 26 | 27 | for (Parameter parameter : parameters) { 28 | Object value = parameterResolver.resolve(parameter, routingContext); 29 | args.add(value); 30 | } 31 | return args.toArray(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/HttpMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message; 2 | 3 | 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | import java.lang.reflect.Parameter; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2020/1/31 11 | */ 12 | public interface HttpMessageHandler { 13 | Object[] handle(RoutingContext routingContext, Parameter[] parameters) throws Exception; 14 | } 15 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/resolver/JsonBodyParameterResolver.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message.resolver; 2 | 3 | import cn.bdqfork.core.util.AnnotationUtils; 4 | import cn.bdqfork.web.constant.ContentType; 5 | import cn.bdqfork.web.route.annotation.RequestBody; 6 | import io.vertx.core.buffer.Buffer; 7 | import io.vertx.core.json.Json; 8 | import io.vertx.core.json.JsonArray; 9 | import io.vertx.core.json.JsonObject; 10 | import io.vertx.ext.web.RoutingContext; 11 | 12 | import java.lang.reflect.Parameter; 13 | 14 | /** 15 | * @author bdq 16 | * @since 2020/2/13 17 | */ 18 | public class JsonBodyParameterResolver extends AbstractParameterResolver { 19 | 20 | @Override 21 | protected Object doResolve(Parameter parameter, RoutingContext routingContext) { 22 | Class parameterType = parameter.getType(); 23 | if (parameterType == JsonObject.class) { 24 | return routingContext.getBodyAsJson(); 25 | } 26 | if (parameterType == JsonArray.class) { 27 | return routingContext.getBodyAsJsonArray(); 28 | } 29 | if (parameterType == String.class) { 30 | return routingContext.getBodyAsString(); 31 | } 32 | Buffer buffer = routingContext.getBody(); 33 | return Json.decodeValue(buffer, parameterType); 34 | } 35 | 36 | @Override 37 | protected boolean resolvable(Parameter parameter, RoutingContext routingContext) { 38 | String contentType = routingContext.request().getHeader(ContentType.CONTENT_TYPE); 39 | return AnnotationUtils.isAnnotationPresent(parameter, RequestBody.class) && ContentType.JSON.equals(contentType); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/resolver/ParameterResolver.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message.resolver; 2 | 3 | import io.vertx.ext.web.RoutingContext; 4 | 5 | import java.lang.reflect.Parameter; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/11 10 | */ 11 | public interface ParameterResolver { 12 | Object resolve(Parameter parameter, RoutingContext routingContext) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/resolver/ParameterResolverFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message.resolver; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/13 10 | */ 11 | public class ParameterResolverFactory { 12 | private List parameterResolvers = new ArrayList<>(); 13 | 14 | public ParameterResolverFactory() { 15 | registerResolver(new ContextParameterResolver()); 16 | registerResolver(new PrimitiveParameterResolver()); 17 | registerResolver(new JsonBodyParameterResolver()); 18 | registerResolver(new XmlBodyParameterResolver()); 19 | registerResolver(new DateParameterResolver()); 20 | } 21 | 22 | public void registerResolver(AbstractParameterResolver parameterResolver) { 23 | parameterResolvers.add(parameterResolver); 24 | } 25 | 26 | public void registerResolver(Collection parameterResolvers) { 27 | this.parameterResolvers.addAll(parameterResolvers); 28 | } 29 | 30 | public ParameterResolver createResolverChain() { 31 | if (parameterResolvers != null && parameterResolvers.size() > 0) { 32 | for (int i = 0; i < parameterResolvers.size() - 1; i++) { 33 | AbstractParameterResolver resolver = parameterResolvers.get(i); 34 | AbstractParameterResolver next = parameterResolvers.get(i + 1); 35 | resolver.setNext(next); 36 | } 37 | return parameterResolvers.get(0); 38 | } 39 | return null; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/message/resolver/XmlBodyParameterResolver.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.message.resolver; 2 | 3 | import cn.bdqfork.core.util.AnnotationUtils; 4 | import cn.bdqfork.web.constant.ContentType; 5 | import cn.bdqfork.web.route.annotation.RequestBody; 6 | import cn.bdqfork.web.util.XmlUtils; 7 | import io.vertx.ext.web.RoutingContext; 8 | 9 | import java.lang.reflect.Parameter; 10 | 11 | /** 12 | * @author bdq 13 | * @since 2020/2/20 14 | */ 15 | public class XmlBodyParameterResolver extends AbstractParameterResolver { 16 | @Override 17 | protected Object doResolve(Parameter parameter, RoutingContext routingContext) throws Exception { 18 | Class parameterType = parameter.getType(); 19 | if (parameterType == String.class) { 20 | return routingContext.getBodyAsString(); 21 | } 22 | String xml = routingContext.getBodyAsString(); 23 | return XmlUtils.fromXml(xml, parameterType); 24 | } 25 | 26 | @Override 27 | protected boolean resolvable(Parameter parameter, RoutingContext routingContext) { 28 | String contentType = routingContext.request().getHeader(ContentType.CONTENT_TYPE); 29 | return AnnotationUtils.isAnnotationPresent(parameter, RequestBody.class) && ContentType.XML.equals(contentType); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/AbstractResponseHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | import io.reactivex.Flowable; 4 | import io.vertx.core.http.HttpServerResponse; 5 | import io.vertx.ext.web.RoutingContext; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/2/12 10 | */ 11 | public abstract class AbstractResponseHandler implements ResponseHandleStrategy { 12 | 13 | @Override 14 | public void handle(RoutingContext routingContext, Object result) throws Exception { 15 | HttpServerResponse httpServerResponse = routingContext.response(); 16 | if (result == null) { 17 | httpServerResponse.end(); 18 | } 19 | if (result instanceof Flowable) { 20 | Flowable flowable = (Flowable) result; 21 | flowable.subscribe(res -> { 22 | if (res != null) { 23 | doHandle(routingContext, res); 24 | } 25 | }); 26 | } else { 27 | doHandle(routingContext, result); 28 | } 29 | } 30 | 31 | protected abstract void doHandle(RoutingContext routingContext, Object result) throws Exception; 32 | } 33 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/HtmlResponseHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | import cn.bdqfork.web.route.ModelAndView; 4 | import cn.bdqfork.web.route.TemplateManager; 5 | import io.vertx.core.http.HttpServerResponse; 6 | import io.vertx.ext.web.RoutingContext; 7 | 8 | /** 9 | * @author bdq 10 | * @since 2020/2/21 11 | */ 12 | public class HtmlResponseHandler extends AbstractResponseHandler { 13 | private TemplateManager templateManager; 14 | 15 | public HtmlResponseHandler(TemplateManager templateManager) { 16 | this.templateManager = templateManager; 17 | } 18 | 19 | @Override 20 | protected void doHandle(RoutingContext routingContext, Object result) throws Exception { 21 | HttpServerResponse response = routingContext.response(); 22 | ModelAndView modelAndView = (ModelAndView) result; 23 | String template = templateManager.getTemplatePath() + "/" + modelAndView.getView() + templateManager.getSuffix(); 24 | templateManager.getTemplateEngine().render(modelAndView.getModel(), template, res -> { 25 | if (res.succeeded()) { 26 | response.end(res.result()); 27 | } else { 28 | routingContext.fail(500, res.cause()); 29 | } 30 | }); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/JsonResponseHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | import io.vertx.core.json.Json; 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/12 9 | */ 10 | public class JsonResponseHandler extends AbstractResponseHandler { 11 | 12 | @Override 13 | protected void doHandle(RoutingContext routingContext, Object result) throws Exception { 14 | routingContext.response().end(Json.encodePrettily(result)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/ResponseHandleStrategy.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/30 9 | */ 10 | public interface ResponseHandleStrategy { 11 | 12 | void handle(RoutingContext routingContext, Object result) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/ResponseHandlerFactory.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | import cn.bdqfork.core.util.StringUtils; 4 | import cn.bdqfork.web.constant.ContentType; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/2/15 12 | */ 13 | public class ResponseHandlerFactory { 14 | private Map responseHandlerMap = new ConcurrentHashMap<>(16); 15 | 16 | public ResponseHandlerFactory() { 17 | registerResponseHandler(ContentType.PLAIN, new TextPlainResponseHandler()); 18 | registerResponseHandler(ContentType.JSON, new JsonResponseHandler()); 19 | registerResponseHandler(ContentType.XML, new XmlResponseHandler()); 20 | } 21 | 22 | public void registerResponseHandler(String contentType, ResponseHandleStrategy responseHandleStrategy) { 23 | responseHandlerMap.put(contentType, responseHandleStrategy); 24 | } 25 | 26 | public ResponseHandleStrategy getResponseHandler(String contentType) { 27 | if (StringUtils.isEmpty(contentType) || !responseHandlerMap.containsKey(contentType)) { 28 | contentType = ContentType.JSON; 29 | } 30 | return responseHandlerMap.get(contentType); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/TextPlainResponseHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/12 9 | */ 10 | public class TextPlainResponseHandler extends AbstractResponseHandler { 11 | 12 | @Override 13 | protected void doHandle(RoutingContext routingContext, Object result) throws Exception { 14 | routingContext.response().end(result.toString()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/route/response/XmlResponseHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.route.response; 2 | 3 | import cn.bdqfork.web.util.XmlUtils; 4 | import io.vertx.ext.web.RoutingContext; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/20 9 | */ 10 | public class XmlResponseHandler extends AbstractResponseHandler { 11 | 12 | @Override 13 | protected void doHandle(RoutingContext routingContext, Object result) throws Exception { 14 | routingContext.response().end(XmlUtils.toXml(result)); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/server/AbstractWebServer.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.server; 2 | 3 | import cn.bdqfork.core.exception.BeansException; 4 | import cn.bdqfork.web.RouterAware; 5 | import cn.bdqfork.web.VertxAware; 6 | import io.vertx.core.Vertx; 7 | import io.vertx.ext.web.Router; 8 | 9 | /** 10 | * @author bdq 11 | * @since 2020/2/12 12 | */ 13 | public abstract class AbstractWebServer implements WebServer, RouterAware, VertxAware { 14 | protected Vertx vertx; 15 | protected Router router; 16 | private boolean running; 17 | 18 | @Override 19 | public void start() throws Exception { 20 | 21 | registerCoreHandler(router); 22 | 23 | registerOptionHandler(router); 24 | 25 | registerRouteMapping(router); 26 | 27 | doStart(); 28 | } 29 | 30 | protected abstract void registerRouteMapping(Router router) throws Exception; 31 | 32 | protected abstract void registerOptionHandler(Router router) throws Exception; 33 | 34 | protected abstract void registerCoreHandler(Router router) throws Exception; 35 | 36 | protected abstract void doStart() throws Exception; 37 | 38 | 39 | @Override 40 | public void stop() throws Exception { 41 | if (running) { 42 | doStop(); 43 | running = false; 44 | } 45 | } 46 | 47 | protected abstract void doStop() throws Exception; 48 | 49 | public boolean isRunning() { 50 | return running; 51 | } 52 | 53 | @Override 54 | public void setRouter(Router router) throws BeansException { 55 | this.router = router; 56 | } 57 | 58 | @Override 59 | public void setVertx(Vertx vertx) throws BeansException { 60 | this.vertx = vertx; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/server/WebServer.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.server; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/2/12 6 | */ 7 | public interface WebServer { 8 | void start() throws Exception; 9 | 10 | void stop() throws Exception; 11 | } 12 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/server/WebVerticle.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.server; 2 | 3 | import io.vertx.core.AbstractVerticle; 4 | import io.vertx.core.Promise; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/21 9 | */ 10 | public class WebVerticle extends AbstractVerticle { 11 | private WebServer webServer; 12 | 13 | public WebVerticle(WebServer webServer) { 14 | this.webServer = webServer; 15 | } 16 | 17 | @Override 18 | public void start(Promise startPromise) throws Exception { 19 | webServer.start(); 20 | startPromise.complete(); 21 | } 22 | 23 | @Override 24 | public void stop(Promise stopPromise) throws Exception { 25 | webServer.stop(); 26 | stopPromise.complete(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/service/JsonMessageCodec.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.service; 2 | 3 | import io.vertx.core.buffer.Buffer; 4 | import io.vertx.core.eventbus.MessageCodec; 5 | import io.vertx.core.json.Json; 6 | 7 | /** 8 | * @author bdq 9 | * @since 2020/1/26 10 | */ 11 | public class JsonMessageCodec implements MessageCodec { 12 | public static final String NAME = "json"; 13 | 14 | @Override 15 | public void encodeToWire(Buffer buffer, Object o) { 16 | buffer.appendBuffer(Json.encodeToBuffer(o)); 17 | } 18 | 19 | @Override 20 | public Object decodeFromWire(int pos, Buffer buffer) { 21 | return Json.decodeValue(buffer); 22 | } 23 | 24 | @Override 25 | public Object transform(Object o) { 26 | return o; 27 | } 28 | 29 | @Override 30 | public String name() { 31 | return NAME; 32 | } 33 | 34 | @Override 35 | public byte systemCodecID() { 36 | return -1; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/service/MethodInvocation.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.service; 2 | 3 | import java.io.Serializable; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/26 9 | */ 10 | public class MethodInvocation implements Serializable { 11 | private String methodName; 12 | private Class[] argumentClasses; 13 | private Object[] arguments; 14 | 15 | public MethodInvocation() { 16 | } 17 | 18 | public MethodInvocation(Method method, Object[] arguments) { 19 | this.methodName = method.getName(); 20 | this.argumentClasses = method.getParameterTypes(); 21 | this.arguments = arguments; 22 | } 23 | 24 | public String getMethodName() { 25 | return methodName; 26 | } 27 | 28 | public void setMethodName(String methodName) { 29 | this.methodName = methodName; 30 | } 31 | 32 | public Class[] getArgumentClasses() { 33 | return argumentClasses; 34 | } 35 | 36 | public void setArgumentClasses(Class[] argumentClasses) { 37 | this.argumentClasses = argumentClasses; 38 | } 39 | 40 | public Object[] getArguments() { 41 | return arguments; 42 | } 43 | 44 | public void setArguments(Object[] arguments) { 45 | this.arguments = arguments; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/service/VerticleProxyHandler.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.service; 2 | 3 | import cn.bdqfork.web.util.EventBusUtils; 4 | import io.reactivex.Flowable; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.eventbus.DeliveryOptions; 7 | import io.vertx.reactivex.core.eventbus.EventBus; 8 | 9 | import java.lang.reflect.InvocationHandler; 10 | import java.lang.reflect.Method; 11 | 12 | /** 13 | * @author bdq 14 | * @since 2020/1/26 15 | */ 16 | public class VerticleProxyHandler implements InvocationHandler { 17 | private DeliveryOptions options; 18 | private Vertx vertx; 19 | private Class targetClass; 20 | 21 | public VerticleProxyHandler(Vertx vertx, Class targetClass) { 22 | this.vertx = vertx; 23 | this.targetClass = targetClass; 24 | this.options = new DeliveryOptions(); 25 | this.options.setCodecName(JsonMessageCodec.NAME); 26 | } 27 | 28 | @Override 29 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 30 | MethodInvocation methodInvocation = new MethodInvocation(method, args); 31 | EventBus eventBus = EventBus.newInstance(vertx.eventBus()); 32 | String address = EventBusUtils.getAddress(targetClass); 33 | return eventBus.rxRequest(address, methodInvocation, options) 34 | .toFlowable() 35 | .flatMap(msg -> { 36 | Object result = msg.body(); 37 | if (result instanceof Throwable) { 38 | throw new IllegalStateException((Throwable) result); 39 | } 40 | return (Flowable) result; 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/util/EventBusUtils.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.util; 2 | 3 | /** 4 | * @author bdq 5 | * @since 2020/1/26 6 | */ 7 | public class EventBusUtils { 8 | public static String getAddress(Class clazz) { 9 | return clazz.getCanonicalName(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/util/VertxUtils.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.util; 2 | 3 | 4 | import io.vertx.core.Vertx; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/1/21 9 | */ 10 | public class VertxUtils { 11 | private static final Vertx vertx; 12 | 13 | static { 14 | vertx = Vertx.vertx(); 15 | } 16 | 17 | public static Vertx getVertx() { 18 | return vertx; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-web/src/main/java/cn/bdqfork/web/util/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package cn.bdqfork.web.util; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.dataformat.xml.XmlMapper; 5 | 6 | /** 7 | * @author bdq 8 | * @since 2020/2/20 9 | */ 10 | public class XmlUtils { 11 | private static XmlMapper xmlMapper = new XmlMapper(); 12 | 13 | public static String toXml(Object instance) throws JsonProcessingException { 14 | return xmlMapper.writeValueAsString(instance); 15 | } 16 | 17 | public static T fromXml(String xml, Class clazz) throws JsonProcessingException { 18 | return xmlMapper.readValue(xml, clazz); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /festival-web/src/main/resources/META-INF/extensions/cn.bdqfork.context.processor.LifeCycleProcessor: -------------------------------------------------------------------------------- 1 | web=cn.bdqfork.web.processor.WebLifeCycleProcessor -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Feb 09 15:42:05 CST 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /images/aop-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/images/aop-design.png -------------------------------------------------------------------------------- /images/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/images/design.png -------------------------------------------------------------------------------- /images/mvc-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdqfork/festival/093db2ce271b2f2bc061e1ddaa873a27c9d34e5d/images/mvc-design.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'festival' 2 | include(':festival-core') 3 | include(':festival-aop') 4 | include(':festival-context') 5 | include(':festival-example') 6 | include(':festival-web') 7 | include(':festival-kotlin-web') 8 | include 'festival-example:kotlin-web' 9 | findProject(':festival-example:kotlin-web')?.name = 'kotlin-web' 10 | include 'festival-example:web' 11 | findProject(':festival-example:web')?.name = 'web' 12 | include 'festival-cache' 13 | 14 | --------------------------------------------------------------------------------