EP框架之开发入门
EP框架是基于springboot封装的,需要开发人员具备Springboot的基础知识,EP框架实现了很多辅助性的注解,让整个框架用起来很方便,而EP框架本身对Springboot是无侵入的,仅仅是辅助开发。
Springboot启动类
下面是springboot的启动类。
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import io.github.junxworks.ep.core.EnableGlobalExceptionHandler;
import io.github.junxworks.ep.core.ds.EnableDynamicDataSource;
import io.github.junxworks.ep.core.security.sql.EnableSQLFilter;
import io.github.junxworks.ep.core.security.xss.EnableXSSFilter;
import io.github.junxworks.ep.core.utils.IPUtils;
import io.github.junxworks.ep.fs.annotation.EnableEPFS;
import io.github.junxworks.ep.scheduler.annotations.EnableEPScheduler;
import io.github.junxworks.ep.sys.annotations.EnableEPSys;
import io.github.junxworks.junx.core.exception.BaseRuntimeException;
@EnableSQLFilter //开启防SQL注入
@EnableXSSFilter //开启防XSS攻击
@EnableDynamicDataSource //开启EP数据源配置
@EnableGlobalExceptionHandler //开启全局异常捕获
@EnableEPSys(init=true) //开启EP基础系统,含人员管理、菜单管理等基础功能,其他模块注解要在这个注解下面
@MapperScan(basePackages = { "io.github.junxworks.ep.*" }, annotationClass = Mapper.class) //io.github.junxworks.ep是ep的mapper扫苗,还可以添加项目自身的mapper扫描,如com.xxx.ccc.mapper
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Application {
static {
try {
IPUtils.initializeServerIP();//如果ip合法,则把IP设置到系统环境变量中,注册到zookeeper的时候会使用到
} catch (Exception e) {
throw new BaseRuntimeException(e);
}
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
启动类中有几个点需要注意一下,@EnableSQLFilter防sql注入注解和@EnableXSSFilter防XSS攻击注解建议开启,@EnableDynamicDataSource动态数据源配置,建议开启,这个是配合DataSourceConfig.java数据源注入配置文件一起使用,@EnableGlobalExceptionHandler全局异常处理器,个人觉得好用,建议开启。@EnableEPSys(init=true)启用EP基础模块,这个必须开启,Mybatis的注解@MapperScan中,必须要扫描EP框架的mapper"io.github.junxworks.ep.*" ,springboot本身要去掉数据源配置类@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }),不然会有冲突。注意,在启动类中调用了IPUtils.initializeServerIP();这个方法,这个方法就是解析当前服务器运行环境,将其IP设置到System环境变量中去,在bootstrap这种配置文件中可以用到,注入的变量名是server.ip。
Session缓存配置
在启动类写好后,需要配置EP框架的Session缓存,EP的认证和鉴权都是基于Shiro框架来的,目前提供了两种session缓存,一个是基于本地内存单节点的EPShiroMemCacheManager,另外一个是基于redis实现的分布式Session缓存EPShiroRedisCacheManager,下面以demo中的config配置为例:
import org.apache.shiro.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.github.junxworks.ep.auth.cache.EPShiroMemCacheManager;
@Configuration
public class Config {
@Bean
public CacheManager epShiroMemCacheManager() {
return new EPShiroMemCacheManager();
}
}
Demo样例中注入的是基于单节点的本地内存Session缓存,这样简单方便,不需要去部署redis。如果这里不注入CacheManager的话,EP默认是基于redis的分布式Session缓存,需要配合Springboot的redis配置来进行使用,至于怎么在Springboot中集成redis,这里不在赘述。
数据库配置以及数据源注入
EP的数据库配置是基于Druid连接池来进行配置,Druid本身是阿里巴巴开源的,想要了解的同学直接百度即可。基于Druid连接池的多数据源数据库配置具体yml配置模板如下:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
main: #主数据源配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:port/dbname?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull
username: xxx
password: "xxx"
initial-size: 1
max-active: 10
min-idle: 1
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
bSource: #B数据源配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:port/dbname?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull
username: xxx
password: "xxx"
initial-size: 1
max-active: 10
min-idle: 1
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
#公共参数
stat-view-servlet:
enabled: false
url-pattern: /druid/*
#login-username: admin
#login-password: admin
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import io.github.junxworks.ep.core.ds.DynamicDataSource;
import io.github.junxworks.ep.core.ds.DynamicDataSourceBuilder;
@Configuration
public class DataSourceConfig
{
@Bean
@ConfigurationProperties("spring.datasource.druid.main")
public DataSource mainDataSource()
{
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.bSource")
public DataSource bDataSource()
{
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dynamicDataSource(DataSource mainDataSource,DataSource bDataSource)
{
return DynamicDataSourceBuilder.create().setPrimarySource("main", mainDataSource).addDataSource("b", bDataSource).build();
}
}
注意,这里通过"spring.datasource.druid.main"配置注入了main这个数据源,然后再把mainDataSource通过dynamicDataSource这个方法,注入到全局DataSource配置中,并且设置成主数据源,bDataSource是其他数据源,这里直接添加到动态数据源的上下文中即可。主数据源与非主数据源的区别就是,主数据源在使用的时候,不需要在Service上加DS注解,系统默认就从主数据源走,而且EP框架是在主数据源上新建系统表结构,因此main数据源必须要存在。非主数据源在使用的时候,需要在service的方法名上添加DS注解,如下所示:
@DS("bSource")
public StudentVo queryStudentById(Long id) {
return tableDemoMapper.queryStudentById(id);
}
注意,目前不支持同一个事物中多数据源的跨事物访问,也就是说已经A方法已经开启一个main数据源的事务了,然后A去调用B方法的接口,这个接口有DS注解,并且是访问非main数据源的数据,那么这里会提示异常,如果一定要在同一个事物中跨数据源访问数据,建议block主当前执行线程,走另外一个线程去访问非main数据源的数据,然后拿给当前线程使用。
EP框架的基础配置已经说完了,下面就可以开始愉快的开发了。