├── .gitignore
├── 1.png
├── 2.png
├── 3.png
├── LICENSE
├── README.MD
├── clojure.gif
├── pom.xml
└── src
└── main
├── java
└── repl
│ ├── R.java
│ └── config
│ ├── StarterAutoConfigure.java
│ └── StarterServiceProperties.java
└── resources
└── META-INF
└── spring.factories
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 | .mvn
19 | .vscode
20 | mvnw
21 | mvnw.cmd
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | /build/
29 |
--------------------------------------------------------------------------------
/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MatrixSeven/clojure-nrepl-starter/71c30342b846d3419d4b2b2610b4af062ecc11a8/1.png
--------------------------------------------------------------------------------
/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MatrixSeven/clojure-nrepl-starter/71c30342b846d3419d4b2b2610b4af062ecc11a8/2.png
--------------------------------------------------------------------------------
/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MatrixSeven/clojure-nrepl-starter/71c30342b846d3419d4b2b2610b4af062ecc11a8/3.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Accelerator
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # clojure-nrepl-starter
2 |
3 | 
4 | 
5 |
6 |
7 |
8 |
9 | ### 这是什么?
10 | 这个是一个Spring-boot的nrepl快速启动组件,在Maven中引入该依赖后可以快速在Spring-boot项目中启动一个`Clojure-Cider-Nrepl`.
11 |
12 | ### 可以做什么?
13 | 启动`Nrepl`后可以在终端使用`lein connect`直接连接到该服务,连接后可以直接获取Spring上下文中的Bean,并且直接调用Bean的方法/查看当前属性状态
14 | 结合`Jrebel`可以实现JavaCode热加载并且Repl不断开,但是在终端里并没有代码补全,如果想体验补全的快感建议使用`Emacs+Cider`环境.
15 |
16 | ### 为啥出来了个这么个玩意
17 | 突发奇想,然后就被无聊的搞出来了
18 |
19 | ### 如何使用
20 | 直接在项目的`pom.xml`里引入依赖
21 | ```xml
22 |
23 | com.github.matrixseven
24 | clojure-nrepl-starter
25 | 1.0.0
26 |
27 | ```
28 | 然后配置
29 | ```properties
30 | #是否启动,默认不启动
31 | clojure.nrepl.state=true
32 | #服务绑定的端口,默认7888
33 | clojure.nrepl.port=7888
34 | #仅在以下环境中启动,默认为dev,优先级高于state
35 | clojure.nrepl.mode=dev,test
36 | ```
37 |
38 | ### 使用场景
39 | 某日你突然要临时发几条`kafka/mq`消息又或者热加载某个`bean`后需要调用某个方法测试,以前可能要写个`Test`用例或者`web`项目调用下接口等等.那么现在so easy,无论是本地还是跑在测试线的环境,只要您开启了`nrepl`服务,你就可以直接连接上去,干你想干的事情,直接发消息/调用某个方法而不要重启/发布你的项目.
40 |
41 |
42 |
43 | ### eg:
44 | #### 体验
45 | 
46 |
47 | #### 直接emacs中启动nrepl链接
48 | 
49 |
50 | #### 或者直接在idea中添加远程repl
51 | 
52 |
53 | #### 然后尝试使用它.
54 | 
55 |
56 | ## Enjoy it!
57 | * 一个emacs配置文件 [https://github.com/MatrixSeven/SEmacs](https://github.com/MatrixSeven/SEmacs)
58 | * 吾爱Java(QQ群):[170936712(点击加入)](https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3D41oCCMn)
--------------------------------------------------------------------------------
/clojure.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MatrixSeven/clojure-nrepl-starter/71c30342b846d3419d4b2b2610b4af062ecc11a8/clojure.gif
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.1.3.RELEASE
9 |
10 |
11 | com.github.matrixseven
12 | clojure-nrepl-starter
13 | 1.0.1-SNAPSHOT
14 | clojure-nrepl-starter
15 | Clojure Nrepl Starter
16 |
17 | 1.8
18 |
19 |
20 |
21 |
22 |
23 | true
24 | always
25 |
26 | https://repo.clojars.org
27 | clojars
28 | Codehaus Snapshots
29 | default
30 |
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter
36 |
37 |
38 | org.slf4j
39 | slf4j-api
40 | 1.7.26
41 |
42 |
43 | org.clojure
44 | clojure
45 | 1.10.0
46 |
47 |
48 | org.clojure
49 | tools.nrepl
50 | 0.2.12
51 |
52 |
53 | cider
54 | cider-nrepl
55 | 0.18.0
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-configuration-processor
60 | true
61 |
62 |
63 | com.alibaba
64 | fastjson
65 | 1.2.62
66 | provided
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-autoconfigure
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | maven-assembly-plugin
122 |
123 |
124 | jar-with-dependencies
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | make-assembly
135 | package
136 |
137 | single
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/src/main/java/repl/R.java:
--------------------------------------------------------------------------------
1 | package repl;
2 |
3 | import clojure.lang.Var;
4 | import com.alibaba.fastjson.JSON;
5 | import repl.config.StarterServiceProperties;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.context.ApplicationContext;
9 | import org.springframework.core.env.Environment;
10 | import org.springframework.stereotype.Service;
11 | import clojure.lang.RT;
12 |
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 |
17 | //=======================================================
18 | // .----.
19 | // _.'__ `.
20 | // .--(^)(^^)---/!\
21 | // .' @ /!!!\
22 | // : , !!!!
23 | // `-..__.-' _.-\!!!/
24 | // `;_: `"'
25 | // .'"""""`.
26 | // /, ya ,\\
27 | // //狗神保佑\\
28 | // `-._______.-'
29 | // ___`. | .'___
30 | // (______|______)
31 | //=======================================================
32 |
33 | /**
34 | * @author Seven
35 | * FileName: R.java
36 | * Created by Seven on 2019/11/12
37 | **/
38 |
39 | @Service
40 | @SuppressWarnings({"all"})
41 | public class R {
42 |
43 | private static Logger logger = LoggerFactory.getLogger(R.class);
44 |
45 | private static final Var EVAL = var("eval");
46 | private static final Var READ_STRING = var("read-string");
47 | private static ApplicationContext applicationContext;
48 | private StarterServiceProperties starterServiceProperties;
49 | private Environment environment;
50 |
51 | public R(StarterServiceProperties properties, ApplicationContext applicationContext, Environment env) {
52 | environment = env;
53 | starterServiceProperties = properties;
54 | repl.R.applicationContext = applicationContext;
55 | }
56 |
57 | private static Var var(String varName) {
58 | return RT.var("clojure.core", varName);
59 | }
60 |
61 | public static T getBean(String name) {
62 | return (T) applicationContext.getBean(name);
63 | }
64 |
65 | public static T getBean(Class clazz) {
66 | return (T) applicationContext.getBean(clazz);
67 | }
68 |
69 |
70 | public static T asJavaObj(Object object, Class tClass) {
71 | String jsonString = JSON.toJSONString(object);
72 | return JSON.parseObject(jsonString, tClass);
73 | }
74 |
75 | public static List asJavaList(Object object, Class tClass) {
76 | String jsonString = JSON.toJSONString(object);
77 | return JSON.parseArray(jsonString, tClass);
78 | }
79 |
80 | public static Object fromJava(Object object) {
81 | String jsonString = JSON.toJSONString(object);
82 | return JSON.parse(jsonString);
83 | }
84 |
85 | public void init() {
86 | final List mode = starterServiceProperties.getMode();
87 | final List active = Arrays.asList(environment.getActiveProfiles());
88 | final boolean runMode = active.stream().anyMatch(mode::contains);
89 | if (starterServiceProperties.getState() && runMode) {
90 | Integer port = starterServiceProperties.getPort();
91 | Thread replThread = new Thread(() -> {
92 | eval("(use '[clojure.tools.nrepl.server :only (start-server)])");
93 | eval("(use '[cider.nrepl :only (cider-nrepl-handler)])");
94 | eval("(def repl-server (start-server :port " + port + " :handler cider-nrepl-handler))");
95 | logger.info("Clojure nrepl is started on port(s): {} ", port);
96 | logger.info("Clojure nrepl services running only on {} mode", mode);
97 | });
98 | replThread.setName("Nrepl-Service");
99 | replThread.start();
100 | } else {
101 | logger.info("Clojure nrepl service is Loaded,but not start");
102 | logger.info("Clojure nrepl service running only on {} mode", mode);
103 | }
104 |
105 | }
106 |
107 | private static T eval(String... code) {
108 | return (T) EVAL.invoke(readString(String.join("\n", code)));
109 | }
110 |
111 | private static T readString(String s) {
112 | return (T) READ_STRING.invoke(s);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/repl/config/StarterAutoConfigure.java:
--------------------------------------------------------------------------------
1 | package repl.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
5 | import org.springframework.context.ApplicationContext;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.core.env.Environment;
9 | import repl.R;
10 |
11 |
12 | //=======================================================
13 | // .----.
14 | // _.'__ `.
15 | // .--(^)(^^)---/!\
16 | // .' @ /!!!\
17 | // : , !!!!
18 | // `-..__.-' _.-\!!!/
19 | // `;_: `"'
20 | // .'"""""`.
21 | // /, ya ,\\
22 | // //狗神保佑\\
23 | // `-._______.-'
24 | // ___`. | .'___
25 | // (______|______)
26 | //=======================================================
27 |
28 | /**
29 | * [Zhihu]https://www.zhihu.com/people/Sweets07
30 | * [Github]https://github.com/MatrixSeven
31 | * Created by Seven on 2019-03-17 16:33
32 | */
33 | @Configuration
34 | @EnableConfigurationProperties(StarterServiceProperties.class)
35 | public class StarterAutoConfigure {
36 |
37 | @Autowired
38 | private StarterServiceProperties properties;
39 |
40 | @Autowired
41 | private Environment env;
42 |
43 | @Autowired
44 | private ApplicationContext applicationContext;
45 |
46 | @Bean(initMethod="init")
47 | public R starterService (){
48 | return new R(properties, applicationContext, env);
49 | }
50 |
51 |
52 | }
--------------------------------------------------------------------------------
/src/main/java/repl/config/StarterServiceProperties.java:
--------------------------------------------------------------------------------
1 | package repl.config;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 |
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | //=======================================================
9 | // .----.
10 | // _.'__ `.
11 | // .--(^)(^^)---/!\
12 | // .' @ /!!!\
13 | // : , !!!!
14 | // `-..__.-' _.-\!!!/
15 | // `;_: `"'
16 | // .'"""""`.
17 | // /, ya ,\\
18 | // //狗神保佑\\
19 | // `-._______.-'
20 | // ___`. | .'___
21 | // (______|______)
22 | //=======================================================
23 |
24 | /**
25 | * [Zhihu]https://www.zhihu.com/people/Sweets07
26 | * [Github]https://github.com/MatrixSeven
27 | * Created by Seven on 2019-03-17 16:33
28 | */
29 | @ConfigurationProperties(prefix = "clojure.nrepl")
30 | public class StarterServiceProperties {
31 | private boolean state = true;
32 | private Integer port = 7888;
33 | private List mode = Arrays.asList("dev","test");
34 |
35 |
36 | public Integer getPort() {
37 | return port;
38 | }
39 |
40 | public void setPort(Integer port) {
41 | this.port = port;
42 | }
43 |
44 | public boolean getState() {
45 | return state;
46 | }
47 |
48 | public void setState(boolean state) {
49 | this.state = state;
50 | }
51 |
52 | public List getMode() {
53 | return mode;
54 | }
55 |
56 | public void setMode(List mode) {
57 | this.mode = mode;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "StarterServiceProperties{" + "state=" + state + ", port=" + port + ", mode=" + mode + '}';
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | repl.config.StarterAutoConfigure
--------------------------------------------------------------------------------