{"id":15292570,"url":"https://github.com/a252937166/quick-spring","last_synced_at":"2025-06-24T07:08:40.738Z","repository":{"id":65392379,"uuid":"119356072","full_name":"a252937166/quick-spring","owner":"a252937166","description":"在main方法中快速使用spring的bean","archived":false,"fork":false,"pushed_at":"2018-09-17T04:56:05.000Z","size":28,"stargazers_count":2,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-06T22:05:29.673Z","etag":null,"topics":["ouyanglol","quickstart","spring"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a252937166.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-29T08:45:17.000Z","updated_at":"2024-05-03T05:09:08.000Z","dependencies_parsed_at":"2023-01-21T04:53:16.695Z","dependency_job_id":null,"html_url":"https://github.com/a252937166/quick-spring","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a252937166%2Fquick-spring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a252937166%2Fquick-spring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a252937166%2Fquick-spring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a252937166%2Fquick-spring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a252937166","download_url":"https://codeload.github.com/a252937166/quick-spring/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a252937166%2Fquick-spring/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258533448,"owners_count":22716269,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ouyanglol","quickstart","spring"],"created_at":"2024-09-30T16:18:52.214Z","updated_at":"2025-06-24T07:08:40.672Z","avatar_url":"https://github.com/a252937166.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n![Jenkins](https://img.shields.io/jenkins/s/https/jenkins.qa.ubuntu.com/view/Precise/view/All%20Precise/job/precise-desktop-amd64_default.svg?style=plastic)\n\n\n# 框架介绍\n\n## 功能\n\n让普通非web项目在使用`main`方法启动的时候，也能随意使用`spring`的`@Service`，`@Autowired`等语法，同时该项目整合了`mybatis`，方便了普通非web项目对数据库的操作。\n\n## 设计思路\n\n我在研究爬虫框架的时候，发现大多是爬虫框架都是通过`main`方法启动的，因为它们并不需要`web`容器，所以为了轻量级，都避开了与`springMVC`的整合。但是我个人习惯了`spring`的语法，同时并不喜欢原生`JdbcTemplate`的操作，更喜欢`mybatis`，所以设计了`Quick Spring`。\n它使普通项目与`spring`的`spring-core`和`spring-context`两个模块简单整合，同时使用`mybatis`，方便了对数据库的操作。\n\n## 源码地址\n\nhttps://github.com/a252937166/quick-spring\n\n# 使用介绍\n\n## 测试项目目录结构\n\n![这里写图片描述](https://qiniu.ouyanglol.com/blog/Quick%20Spring%E2%80%94%E2%80%94%E4%B8%80%E6%AC%BE%E5%9C%A8main%E6%96%B9%E6%B3%95%E4%B8%AD%E4%BD%BF%E7%94%A8spring%E8%AF%AD%E6%B3%95%E7%9A%84%E6%95%8F%E6%8D%B7%E6%A1%86%E6%9E%B61.png)\n\n**图（1）**\n\n## 导入maven\n\n如何创建maven项目就不多介绍了，不懂得同学可以看一下[idea如何创建maven项目（一）](http://blog.csdn.net/mr_ooo/article/details/53871828)，超简单的。\n\n### maven地址：\n\n```\n   \u003cdependency\u003e\n      \u003cgroupId\u003ecom.ouyanglol\u003c/groupId\u003e\n      \u003cartifactId\u003equick-spring\u003c/artifactId\u003e\n      \u003cversion\u003e1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n![这里写图片描述](https://qiniu.ouyanglol.com/blog/Quick%20Spring%E2%80%94%E2%80%94%E4%B8%80%E6%AC%BE%E5%9C%A8main%E6%96%B9%E6%B3%95%E4%B8%AD%E4%BD%BF%E7%94%A8spring%E8%AF%AD%E6%B3%95%E7%9A%84%E6%95%8F%E6%8D%B7%E6%A1%86%E6%9E%B62.png)\n\n**图（2）**\n \n## 配置文件\n\n`Quick Spring`会扫描`resource`下以`quick-`开头的`xml`文件，默认为`spring`的配置文件，配置语法和普通`spring`配置一样，我这里提供简单模板，需要个性化配置的，可以自己改。\n \n### quick-applicationContext.xml\n \n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xmlns:context=\"http://www.springframework.org/schema/context\"\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\"\u003e\n\n    \u003c!--选择最流行的druid连接池--\u003e\n    \u003cbean id=\"mybatisDataSource\" class=\"com.alibaba.druid.pool.DruidDataSource\"\u003e\n        \u003cproperty name=\"driverClassName\" value=\"${database.driverClassName}\"/\u003e\n        \u003cproperty name=\"url\" value=\"${database.url}\"/\u003e\n        \u003cproperty name=\"username\" value=\"${database.username}\"/\u003e\n        \u003cproperty name=\"password\" value=\"${database.password}\"/\u003e\n\n        \u003c!-- 初始化连接数量 --\u003e\n        \u003cproperty name=\"initialSize\" value=\"${druid.initialSize}\" /\u003e\n        \u003c!-- 最小空闲连接数 --\u003e\n        \u003cproperty name=\"minIdle\" value=\"${druid.minIdle}\" /\u003e\n        \u003c!-- 最大并发连接数 --\u003e\n        \u003cproperty name=\"maxActive\" value=\"${druid.maxActive}\" /\u003e\n        \u003c!-- 配置获取连接等待超时的时间 --\u003e\n        \u003cproperty name=\"maxWait\" value=\"${druid.maxWait}\" /\u003e\n\n        \u003c!-- 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒 --\u003e\n        \u003cproperty name=\"timeBetweenEvictionRunsMillis\" value=\"${druid.timeBetweenEvictionRunsMillis}\" /\u003e\n\n        \u003c!-- 配置一个连接在池中最小生存的时间，单位是毫秒 --\u003e\n        \u003cproperty name=\"minEvictableIdleTimeMillis\" value=\"${druid.minEvictableIdleTimeMillis}\" /\u003e\n        \u003cproperty name=\"validationQuery\" value=\"${druid.validationQuery}\" /\u003e\n        \u003cproperty name=\"testWhileIdle\" value=\"${druid.testWhileIdle}\" /\u003e\n        \u003cproperty name=\"testOnBorrow\" value=\"${druid.testOnBorrow}\" /\u003e\n        \u003cproperty name=\"testOnReturn\" value=\"${druid.testOnReturn}\" /\u003e\n\n        \u003c!-- 打开PSCache，并且指定每个连接上PSCache的大小 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。 --\u003e\n        \u003cproperty name=\"poolPreparedStatements\" value=\"${druid.poolPreparedStatements}\" /\u003e\n        \u003cproperty name=\"maxPoolPreparedStatementPerConnectionSize\"\n                  value=\"${druid.maxPoolPreparedStatementPerConnectionSize}\" /\u003e\n\n        \u003c!-- 配置监控统计拦截的filters --\u003e\n        \u003cproperty name=\"filters\" value=\"${druid.filters}\" /\u003e\n\n    \u003c/bean\u003e\n\n    \u003cbean id=\"sqlSessionFactory\" class=\"org.mybatis.spring.SqlSessionFactoryBean\"\u003e\n        \u003cproperty name=\"dataSource\" ref=\"mybatisDataSource\"/\u003e\n        \u003cproperty name=\"mapperLocations\"\u003e\n            \u003clist\u003e\n                \u003cvalue\u003eclasspath:mapper/*.xml\u003c/value\u003e\n            \u003c/list\u003e\n        \u003c/property\u003e\n    \u003c/bean\u003e\n\n    \u003cbean class=\"org.mybatis.spring.mapper.MapperScannerConfigurer\"\u003e\n        \u003cproperty name=\"basePackage\" value=\"com.ouyang.dao\"/\u003e\n        \u003cproperty name=\"sqlSessionFactoryBeanName\" value=\"sqlSessionFactory\"/\u003e\n    \u003c/bean\u003e\n\n    \u003c!--选择自动扫描路径--\u003e\n    \u003ccontext:component-scan base-package=\"com.ouyang\"/\u003e\n    \u003c!--选择配置文件--\u003e\n    \u003ccontext:property-placeholder location=\"classpath:application.properties\" /\u003e\n\u003c/beans\u003e\n```\n其中`\u003ccontext:component-scan base-package=\"com.ouyang\"/\u003e`，`\u003cproperty name=\"basePackage\" value=\"com.ouyang.dao\"/\u003e`和`\u003ccontext:property-placeholder location=\"classpath:application.properties\" /\u003e`大家根据自己项目路径自己改一下。\n\n### log4j.properties\n\n```\nlog4j.rootLogger=DEBUG,stdout,D,E,I\n### 输出到控制台 ###\nlog4j.appender.stdout = org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.Target = System.out\nlog4j.appender.stdout.layout = org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r:%L] - [%p] %m%n\n\n### 输出到日志文件 ###\nlog4j.appender.D = org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.D.File = /data/log/quick.debug.log\nlog4j.appender.D.Append = true\nlog4j.appender.D.Threshold = DEBUG\nlog4j.appender.D.layout = org.apache.log4j.PatternLayout\nlog4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n\n\n### 输出到日志文件 ###\nlog4j.appender.I = org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.I.File = /data/log/quick.info.log\nlog4j.appender.I.Append = true\nlog4j.appender.I.Threshold = INFO\nlog4j.appender.I.layout = org.apache.log4j.PatternLayout\nlog4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n\n\n### 保存异常信息到单独文件 ###\nlog4j.appender.E = org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.E.File = /data/log/quick.error.log\nlog4j.appender.E.Append = true\nlog4j.appender.E.Threshold = ERROR\nlog4j.appender.E.layout = org.apache.log4j.PatternLayout\nlog4j.appender.E.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n\n\n```\n\n我顺便把日志也整合了，日志我用的是`slf4j`整合`log4j`，也是当下最流行的选择，使用方法很简单，等下java代码里简单介绍一下。\n其中日志的输出路径，大家可以根据自己的需求修改一下。\n \n### application.properties\n\n```\ndatabase.driverClassName=com.mysql.cj.jdbc.Driver\ndatabase.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8\u0026useSSL=false\ndatabase.username=mysql\ndatabase.password=123456\n\n\ndruid.initialSize=10\ndruid.minIdle=6\ndruid.maxActive=50\ndruid.maxWait=60000\ndruid.timeBetweenEvictionRunsMillis=60000\ndruid.minEvictableIdleTimeMillis=300000\ndruid.validationQuery=SELECT 1\ndruid.testWhileIdle=true\ndruid.testOnBorrow=false\ndruid.testOnReturn=false\ndruid.poolPreparedStatements=false\ndruid.maxPoolPreparedStatementPerConnectionSize=20\ndruid.filters=wall,stat\n\n```\n\n统一记录配置信息。\n\n## 启动类\n\nMyQuick.java\n\n```\npackage com.ouyang.quick;\n\nimport com.ouyang.service.TestService;\nimport com.ouyanglol.annotation.QuickSpring;\nimport org.springframework.beans.factory.annotation.Autowired;\n\n/**\n * Package: com.ouyang.quick\n *\n * @Author: Ouyang\n * @Date: 2018/1/29\n */\n@QuickSpring\npublic class MyQuick {\n    @Autowired\n    TestService testService;\n\n    public void test() {\n        testService.test();\n        System.out.println(\"MyQuick\");\n    }\n}\n\n\n```\n我个人建议启动类都放在`quick`的包路径下（当然也可以自定义），只需要加上`@QuickSpring`注释就行了，启动类中可以随意使用`spring`注释，`name`默认为类名，当然可以可自己修改。\n\nTestQuick.java（自定义`name`和包路径）\n从项目路径可以看到，该文件在`com.ouyang.test`包路径下。\n```\npackage com.ouyang.test;\n\n\nimport com.ouyang.model.Test;\nimport com.ouyang.service.TestService;\nimport com.ouyanglol.annotation.QuickSpring;\nimport org.springframework.beans.factory.annotation.Autowired;\n\n/**\n * Package: com.ouyang.test\n *\n * @Author: Ouyang\n * @Date: 2018/1/29\n */\n@QuickSpring(name = \"myTest\")\npublic class TestQuick {\n    @Autowired\n    TestService testService;\n\n    public void  test() {\n        testService.test();\n        System.out.println(\"TestQuick\");\n    }\n\n    public void update(Test test) {\n        testService.update(test);\n    }\n}\n\n\n```\n\n## Server类\n\nTestServer.java\n\n```\npackage com.ouyang.service;\n\nimport com.ouyang.dao.TestMapper;\nimport com.ouyang.model.Test;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\n/**\n * Package: com.ouyang.service\n *\n * @Author: Ouyang\n * @Date: 2018/1/26\n */\n@Service\npublic class TestService {\n    \n    private final Logger logger = LoggerFactory.getLogger(this.getClass());\n    \n    @Autowired\n    TestMapper testMapper;\n    public void test() {\n        \n        logger.info(\"这是{}方法\",\"test()\");\n        \n        System.out.println(\"test Service\");\n    }\n\n    public void find(Integer id) {\n\n        logger.info(\"这是{}方法\",\"find()\");\n        \n        Test test = testMapper.selectByPrimaryKey(id);\n        System.out.println(test.getText());\n    }\n    public void update(Test test) {\n        testMapper.updateByPrimaryKeySelective(test);\n    }\n}\n\n```\n\n其中`logger`是典型的`slf4j`框架的使用方法，`testMapper`是`mybatis`的mapper，mapper的代码就没必要贴出来了，需要使用`mybatis`的自己使用工具生成就是了。\n生成工具（实现中文注释）地址：https://github.com/a252937166/mybatis-generator-core-1.3.2\n\n## main方法启动\n\nApp.java \n\n```\npackage com.ouyang;\n\n\n\nimport com.ouyang.model.Test;\nimport com.ouyang.quick.MyQuick;\nimport com.ouyang.service.TestService;\nimport com.ouyang.test.TestQuick;\nimport com.ouyanglol.core.QuickBase;\n\n/**\n * Hello world!\n *\n */\npublic class App {\n    public static void main( String[] args ) {\n\n        QuickBase quickBase = QuickBase.getInstance();//初始化quick包下的启动类\n        MyQuick quick = (MyQuick) quickBase.getQuick(\"MyQuick\");\n        quick.test();\n\n        QuickBase quickBase1 = QuickBase.getInstance(\"test\");//初始化test包下的启动类\n        TestQuick quick1 = (TestQuick) quickBase1.getQuick(\"myTest\");\n        quick1.test();\n\n        TestService testService = (TestService) quickBase.getBean(\"testService\");\n        testService.test();\n\n        testService.find(1);\n        testService.find(2);\n        testService.find(3);\n        testService.find(4);\n\n\n    }\n}\n\n```\n首先使用`QuickBase quickBase = QuickBase.getInstance();`初始化需要使用的启动类，如果不是在`quick`包下，需要手动填入包名。\n```\nquickBase.getQuick();\n```\n这个方法获取启动类，其中`myTest`与`@QuickSpring(name = \"myTest\")`中的`name`对应，不填`name`就默认是类名。获取之后就是随意调用方法了。直接启动`main`方法就能使用了。\n\n```\nquickBase.getBean(\"testService\")\n```\n这个方法可以单独获取spring的bean对线。\n\n## 测试结果\n\n![这里写图片描述](https://qiniu.ouyanglol.com/blog/Quick%20Spring%E2%80%94%E2%80%94%E4%B8%80%E6%AC%BE%E5%9C%A8main%E6%96%B9%E6%B3%95%E4%B8%AD%E4%BD%BF%E7%94%A8spring%E8%AF%AD%E6%B3%95%E7%9A%84%E6%95%8F%E6%8D%B7%E6%A1%86%E6%9E%B63.png)\n\n**图(3)**\n\n很明显，`logger`和`mybatis`都成功使用了。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa252937166%2Fquick-spring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa252937166%2Fquick-spring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa252937166%2Fquick-spring/lists"}