<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JOxygen輕量級(jí) Java 框架

          聯(lián)合創(chuàng)作 · 2023-09-20 04:14

          JOxygen

          輕量級(jí)Java框架

          介紹

          一個(gè)輕量級(jí)Java框架

          oxygen-core 核心部分

          • 基于cglib的aop實(shí)現(xiàn)

          • 提供緩存管理和基于注解的緩存,內(nèi)置LocalCache和Ehcache實(shí)現(xiàn),可擴(kuò)展

          • 配置管理,支持${attrs.key:defaultValue}表達(dá)式獲取配置

          • 加解密管理,提供加解密服務(wù)內(nèi)置基礎(chǔ)加密實(shí)現(xiàn),例如SHA-1、SHA-256、MD5

          • 異常管理,提供異常包裝,統(tǒng)一異常編碼,便于國(guó)際化

          • 提供基于構(gòu)造器注入的ioc(原因:依賴鏈清晰,并可任意切換ioc實(shí)現(xiàn))

          • 定時(shí)任務(wù)服務(wù),內(nèi)置提供了基于注解的定時(shí)任務(wù)服務(wù)

          ├─ src/main
            │─ java/.../core  //oxygen-core代碼目錄
            │  │- aop //aop實(shí)現(xiàn)目錄
            │  │- cache //緩存實(shí)現(xiàn)目錄
            │  │- config  //配置實(shí)現(xiàn)目錄
            │  │- constant  //常量目錄
            │  │- convert  //類型轉(zhuǎn)換實(shí)現(xiàn)目錄
            │  │- crypto  //密碼加密目錄
            │  │- domain  //基礎(chǔ)實(shí)體目錄
            │  │- exception  //異常管理目錄
            │  │- io  //io讀寫目錄
            │  │- ioc  //ioc實(shí)現(xiàn)目錄
            │  │- job  //定時(shí)任務(wù)實(shí)現(xiàn)目錄
            │  │- scan  //類掃描實(shí)現(xiàn)目錄
            │  │- util  //工具類目錄
            │  │- Bootstrap.java  //框架啟動(dòng)引導(dǎo)類
            │  └- Plugin.java   //插件接口
            └─ resources/META-INF/services
               └- ...core.Plugin  //Plugin服務(wù)實(shí)現(xiàn)配置文件

          oxygen-jdbc jdbc實(shí)現(xiàn)

          • 小巧簡(jiǎn)單的jdbc實(shí)現(xiàn),純jdk實(shí)現(xiàn),無第三方j(luò)ar

          • 支持多數(shù)據(jù)源

          • 基于sql進(jìn)行crud,不提供類似Hibernate的鏈?zhǔn)椒椒ǎㄔ颍簊ql作為數(shù)據(jù)庫領(lǐng)域的DSL,已經(jīng)很自然優(yōu)雅,Less is more)

          ├─ src/main
            │─ java/.../jdbc  //oxygen-jdbc代碼目錄
            │  │- config  //配置數(shù)據(jù)源目錄
            │  │- handler  //處理器目錄,包括結(jié)果集處理 行處理 列處理
            │  │- interceptor  //攔截器目錄,攔截sql執(zhí)行前后及異常
            │  │- record  //基礎(chǔ)crud
            │  │- Jdbc.java  //Jdbc核心操作類,提供crud操作
            │  │- JdbcException.java  //jdbc異常封裝
            │  └- JdbcPlugin.java   //jdbc插件,與oxygen-core配套使用
            └─ resources/META-INF/services
               │- ...handler.ColumnHandler //列處理服務(wù)配置文件
               └- ...core.Plugin  //增加jdbcPlugin服務(wù)實(shí)現(xiàn),與oxygen-core配套使用

          oxygen-web

          • 項(xiàng)目使用了Servlet3.0的ServletContainerInitializer接口

          • 在servlet中可自動(dòng)加載,不需要在web.xml中配置

          • 使用@Router標(biāo)記路由文件

          • 使用@Mapping標(biāo)記請(qǐng)求路徑處理方法

          • 參數(shù)綁定的取值域使用@Param,@HeaderParam,@CookieParam,@PathParam指定,默認(rèn)為@Param

          • 參數(shù)綁定支持簡(jiǎn)單類型 + Map<String,Object> + 用戶實(shí)體類

          • 支持返回Json、視圖或自定義實(shí)現(xiàn)(文件下載等)

          ├─ src/main
            │─ java/.../web  //oxygen-web代碼目錄
            │  │- handler //參數(shù)綁定處理
            │  │- http //http請(qǐng)求解析
            │  │- mapping  //url映射,參數(shù)映射相關(guān)注解和實(shí)體
            │  │- router  //一個(gè)示例路由(獲取服務(wù)器時(shí)間)
            │  │- server  //內(nèi)置server接口和啟動(dòng)類
            │  │- view  //視圖解析
            │  │- DefaultWebAppInitializer.java  //默認(rèn)初始化實(shí)現(xiàn)
            │  │- DispatcherServlet.java  //路由分發(fā)器
            │  │- WebAppInitializer.java  //web自動(dòng)初始化接口,提供給用戶自定義使用
            │  │- WebContainerInitializer.java  //容器自動(dòng)初始化
            │  │- WebConf.java  //web配置
            │  └- WebPlugin.java  //web插件
            └─ resources/META-INF/services
                │- ...ServletContainerIntializer //servlet3.0規(guī)范
                │- ...core.Plugin  //增加web插件
                │- ...ParamHandler //參數(shù)處理服務(wù)
                │- ...RequestParse //請(qǐng)求解析服務(wù)
                └- ...ViewResolver //視圖解析服務(wù)

          特性

          • 輕量級(jí),注釋完善,使用簡(jiǎn)單

          • 使用ServiceLoader加載插件,易于擴(kuò)展

          安裝

          添加依賴到你的 pom.xml:

          <!-- 核心包 包含aop ioc 異常處理 緩存 定時(shí)任務(wù)等 -->
          <dependency>
              <groupId>vip.justlive</groupId>
              <artifactId>oxygen-core</artifactId>
              <version>${oxygen.version}</version>
          </dependency>
          
          <!-- jdbc實(shí)現(xiàn) 可單獨(dú)使用 -->
          <dependency>
              <groupId>vip.justlive</groupId>
              <artifactId>oxygen-jdbc</artifactId>
              <version>${oxygen.version}</version>
          </dependency>
          
          <!-- web實(shí)現(xiàn) 已依賴了core -->
          <dependency>
              <groupId>vip.justlive</groupId>
              <artifactId>oxygen-web</artifactId>
              <version>${oxygen.version}</version>
          </dependency>
          
          <!-- 已依賴了web 并提供了embeded tomcat -->
          <dependency>
              <groupId>vip.justlive</groupId>
              <artifactId>oxygen-web-tomcat</artifactId>
              <version>${oxygen.version}</version>
          </dependency>

          快速開始

          基礎(chǔ)返回

          使用 Resp 作為返回

          // 成功返回 code 00000
          Resp.success(Object obj);
          
          // 錯(cuò)誤返回 默認(rèn)code 99999
          Resp.error(String msg);
          
          // 錯(cuò)誤返回 自定義code
          Resp.error(String code, String msg);

          異常處理

          使用 Exceptions 拋出異常

          // 創(chuàng)建 ErrorCode
          ErrorCode err = Exceptions.errorCode(String module, String code);
          ErrorCode err = Exceptions.errorMessage(String module, String code, String message);
          
          // 拋出unchecked異常
          throw Exceptions.wrap(Throwable e);
          throw Exceptions.wrap(Throwable e, String code, String message);
          throw Exceptions.wrap(Throwable e, ErrorCode errorCode, Object... arguments);
          
          // 拋出業(yè)務(wù)異常 不含堆棧信息
          throw Exceptions.fail(ErrorCode errCode, Object... params);
          throw Exceptions.fail(String code, String message, Object... params);
          
          // 拋出故障異常 包含堆棧信息
          throw Exceptions.fault(ErrorCode errCode, Object... params);
          throw Exceptions.fault(String code, String message, Object... params);
          throw Exceptions.fault(Throwable e, ErrorCode errCode, Object... params);
          throw Exceptions.fault(Throwable e, String code, String message, Object... params)

          IOC

          通過注解使用IOC容器

          // 在配置文件中添加掃包路徑
          main.class.scan=com.xxx.xxx,com.aaa.bbb
          
          // 使用 @Configuration 和 @Bean
          @Configuration
          public class Conf {
           
            @Bean
            Inter noDepBean() {
              return new NoDepBean();
            }
          }
          
          // 使用 @Bean 和 @Inject
          @Bean("depBean")
          public class DepBean implements Inter {
          
            private final NoDepBean noDepBean;
          
            @Inject
            public DepBean(NoDepBean noDepBean) {
              this.noDepBean = noDepBean;
            }
            
            ...
          }
          
          // 運(yùn)行時(shí)獲取bean
          Inter inter = BeanStore.getBean("depBean", Inter.class);

          AOP

          通過注解使用AOP

          // 定義使用了Log注解的方法aop處理
          @Before(annotation = Log.class)
          public void log(Invocation invocation) {
            ...
          }
          
          // 目標(biāo)方法添加注解
          @Log
          public void print() {
            ...
          }

          定時(shí)任務(wù)

          使用注解 @Scheduled 標(biāo)記一個(gè)方法需要作為定時(shí)任務(wù)

          onApplicationStart(), cron(), fixedDelay(), or fixedRate() 必須配置其中一個(gè)

          // 固定延遲任務(wù) 任務(wù)結(jié)束時(shí)間-下一個(gè)開始時(shí)間間隔固定
          @Scheduled(fixedDelay = "500")
          public void run1() {
            ...
          }
          
          // 固定周期任務(wù) 任務(wù)開始時(shí)間-下一個(gè)開始時(shí)間固定
          @Scheduled(fixedRate = "600")
          public void run2() {
            ...
          }
          
          // cron任務(wù),并且程序啟動(dòng)后異步執(zhí)行一次
          @Scheduled(cron = "0/5 * * * * ?", onApplicationStart = true, async = true)
          public void run3() {
            ...
          }

          緩存

          使用緩存有兩種方式:

          • JCache.cache() 獲取緩存然后調(diào)用api

          • 使用 @Cacheable 注解給方法添加緩存

          // 使用緩存api 
          Cache cache = JCache.cache(cacheName);
          T value = cache.get(key, clazz);
          cache.set(key, value, duration, timeUnit);
          ...
          
          // 使用注解
          @Cacheable
          public Object method() {
            ...
          }
          
          @Cacheable(key = "args[0]", duration = 10, timeUnit = TimeUnit.MINUTES)
          public Object method(Object arg0, Object arg1) {
            ...
          }

          Jdbc

          基礎(chǔ)使用

          • 可配置多數(shù)據(jù)源

          • 使用Jdbc進(jìn)行crud

          • 使用ResultSetHandler 進(jìn)行自定義類型轉(zhuǎn)換處理

          • 開啟關(guān)閉事務(wù)

          // 單獨(dú)使用 需要自己創(chuàng)建并添加數(shù)據(jù)源
          ...
          // 添加主數(shù)據(jù)源
          Jdbc.addPrimaryDataSource(DataSource dataSource)
          // 添加多數(shù)據(jù)源
          Jdbc.addDataSource(String name, DataSource dataSource)
          
          // crud
          T Jdbc.query(String sql, Class<T> clazz, Object... params)
          List<T> Jdbc.queryForList(String sql, Class<T> clazz, Object... params)
          Map<String, Object> Jdbc.queryForMap(String sql, Object... params)
          List<Map<String, Object>> Jdbc.queryForMapList(String sql, Object... params)
          // 可自定義返回處理
          T Jdbc.query(String sql, ResultSetHandler<T> handler, Object... params)
          
          int Jdbc.update(String sql, Object... params)
          
          // 開啟主數(shù)據(jù)源的事務(wù)
          Jdbc.startTx()
          // 開啟指定數(shù)據(jù)源的事務(wù)
          Jdbc.startTx(String dataSourceName)
          
          // 關(guān)閉主數(shù)據(jù)源的事務(wù)
          Jdbc.closeTx()
          // 關(guān)閉指定數(shù)據(jù)源的事務(wù)
          Jdbc.closeTx(String dataSourceName)
          
          
          // 回滾事務(wù)
          Jdbc.rollbackTx()
          // 回滾指定數(shù)據(jù)源的事務(wù)
          Jdbc.rollbackTx(String dataSourceName)
          
          // 基礎(chǔ)crud
          Option opt = new Option()
          ...
          Record.insert(opt)
          Record.findById(Option.class, 1)
          Record.find(opt)
          Record.update(opt)
          Record.deleteById(Option.class, 1)
          Record.delete(opt);
          
          
          // 配合oxygen-core使用, 只需在配置文件中配置數(shù)據(jù)源即可自動(dòng)裝載
          // 多數(shù)據(jù)源名稱
          datasource.multi=a
          // 主數(shù)據(jù)源
          datasource.logSql=true
          datasource.driverClassName=org.h2.Driver
          datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
          datasource.username=sa
          datasource.password=sa
          
          // 數(shù)據(jù)源a
          datasource.a.driverClassName=org.h2.Driver
          datasource.a.url=jdbc:h2:mem:a;DB_CLOSE_DELAY=-1
          datasource.a.username=sa
          datasource.a.password=sa

          自定義列類型轉(zhuǎn)換

          • 實(shí)現(xiàn) ColumnHandler 接口進(jìn)行自定義處理

          • 增加 META-INF/services/vip.justlive.oxygen.jdbc.handler.ColumnHandler 文件,添加實(shí)現(xiàn)類的類名

          public class MyColumnHandler implements ColumnHandler {
          
            @Override
            public boolean supported(Class<?> type) {
              ...
            }
          
            @Override
            public Object fetch(ResultSet rs, int index) throws SQLException {
              ...
            }
          }
          
          // 新增或修改 META-INF/services/vip.justlive.oxygen.jdbc.handler.ColumnHandler 添加自定義類名
          xxx.xxx.MyColumnHandler

          增加jdbc攔截

          • 實(shí)現(xiàn) JdbcInterceptor 接口

          • 調(diào)用 Jdbc.addJdbcInterceptor 添加攔截

          // 內(nèi)置的sql打印攔截
          @Slf4j
          public class LogSqlJdbcInterceptor implements JdbcInterceptor {
          
            @Override
            public void before(String sql, List<Object> params) {
              if (log.isDebugEnabled()) {
                log.debug("execute sql: {} -> params: {}", sql, params);
              }
            }
          }
          
          // 添加攔截器
          Jdbc.addJdbcInterceptor(JdbcInterceptor interceptor)

          web

          基礎(chǔ)使用

          • 使用@Router @Mapping @Param...等注解進(jìn)行定義路由類和請(qǐng)求方法以及綁定參數(shù)

          • 使用View進(jìn)行視圖跳轉(zhuǎn),非void,View的返回值默認(rèn)使用json處理

          • 線程內(nèi)使用Request.current(),Response.current()獲取請(qǐng)求和返回

          // 使用 @Router標(biāo)記路由
          @Router("/common")
          public class CommonRouter {
          
            // 標(biāo)記請(qǐng)求路徑和請(qǐng)求方式,默認(rèn)支持所有請(qǐng)求 當(dāng)返回值不是void且非View則為返回json
            @Mapping(value = "/localDate",method = HttpMethod.GET)
            public Resp localDate() {
              return Resp.success(
                      LocalDate.now().plusDays(offset).atStartOfDay(ZoneOffset.systemDefault()).toInstant()
                          .toEpochMilli());
            }
          
            // 頁面渲染 需要返回View
            @Mapping("/index")
            public View index() {
              View view = new View();
              view.setPath("/index.jsp");
              return view;
            }
            
            // 重定向
            @Mapping("/view")
            public View index() {
              View view = new View();
              // 相對(duì)路徑為容器內(nèi)跳轉(zhuǎn) 使用http://xxx則絕對(duì)跳轉(zhuǎn)
              view.setPath("/index");
              view.setRedirect(true);
              return view;
            }
            
            // 文件下載
            @Mapping("download")
            public void download(HttpServletResponse resp) throws IOException {
              resp.setCharacterEncoding("utf-8");
              resp.setContentType("application/octet-stream;charset=utf-8");
              resp.setHeader("Content-disposition", "attachment;filename=xx.txt");
              Files.copy(new File("xxx.txt"), resp.getOutputStream());
            }
          }
          
          // 獲取當(dāng)前線程的Request Response
          Request.current()
          Response.current()
          
          // 配置404錯(cuò)誤頁面跳轉(zhuǎn)
          web.error.404.page=
          // 配置404自定義處理
          web.error.404.handler=
          // 配置500錯(cuò)誤頁面跳轉(zhuǎn)
          web.error.500.page=
          // 配置500自定義處理
          web.error.500.handler=

          自定義視圖解析

          • 實(shí)現(xiàn)ViewResolver接口

          • 通過ServiceLoaderWebPlugin.addViewResolver的方式進(jìn)行添加自定義視圖解析

          // 內(nèi)置的重定向和json解析器
          public class DefaultViewResolver implements ViewResolver {
          
            @Override
            public boolean supported(Object data) {
              // 重定向
              if (data != null && data.getClass() == View.class && ((View) data).isRedirect()) {
                return true;
              }
              // null 或者 非view 返回json
              return data == null || data.getClass() != View.class;
            }
          
            @Override
            public void resolveView(HttpServletRequest request, HttpServletResponse response, Object data) {
              try {
                if (data != null && data.getClass() == View.class) {
                  View view = (View) data;
                  String redirectUrl = view.getPath();
                  if (!redirectUrl.startsWith(Constants.HTTP_PREFIX) && !redirectUrl
                      .startsWith(Constants.HTTPS_PREFIX)) {
                    redirectUrl = request.getContextPath() + view.getPath();
                  }
                  response.sendRedirect(redirectUrl);
                } else {
                  response.getWriter().print(JSON.toJSONString(data));
                }
              } catch (IOException e) {
                throw Exceptions.wrap(e);
              }
            }
          }

          添加web啟動(dòng)執(zhí)行類

          只需實(shí)現(xiàn)WebAppInitializer接口,容器會(huì)自動(dòng)加載

          public class MyWebAppInitializer implements WebAppInitializer {
            @Override
            public void onStartup(ServletContext context) {
              ...
            }
            @Override
            public int order() {
              ...
            }
          }

          使用內(nèi)置容器啟動(dòng)

          • 依賴 oxygen-web-tomcat

          • 在main中使用 Server.start啟動(dòng)

          <!-- 已依賴了web 并提供了embeded tomcat -->
          <dependency>
              <groupId>vip.justlive</groupId>
              <artifactId>oxygen-web-tomcat</artifactId>
              <version>${oxygen.version}</version>
          </dependency>
          
          
          public static void main(String[] args) {
            // 啟動(dòng)容器
            Server.start();
            ...
            // 關(guān)閉容器
            Server.stop();
          }
          瀏覽 11
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久草青青草 | 极品人妻在线 | 99久免费视频 | 特级黄色录像国产 | 亚洲无码精品久久 |