基础框架新增PreLoad支持,代理服务增加初始化数据库逻辑

This commit is contained in:
aoshiguchen
2022-07-31 14:50:28 +08:00
parent 4eb344fe94
commit 0a1e849beb
13 changed files with 420 additions and 12 deletions
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PreLoad {
String value() default "preLoad";
}
@@ -29,6 +29,7 @@ import fun.asgc.neutrino.core.exception.BeanException;
import fun.asgc.neutrino.core.util.*;
import lombok.extern.slf4j.Slf4j;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -544,7 +545,8 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* 运行
*/
private void run() {
beanCache.values().stream().filter(b -> b.getStatus().getStatus() < BeanStatus.RUNNING.getStatus()).forEach(b -> {
beanCache.values().stream().filter(b -> b.getStatus().getStatus() < BeanStatus.RUNNING.getStatus())
.sorted(Comparator.comparing(BeanWrapper::getOrder)).forEach(b -> {
try {
getOrNew(b);
b.run(getEnvironment().getMainArgs());
@@ -22,6 +22,7 @@
package fun.asgc.neutrino.core.context;
import fun.asgc.neutrino.core.annotation.PreLoad;
import fun.asgc.neutrino.core.base.GlobalConfig;
import fun.asgc.neutrino.core.bean.BeanFactoryAware;
import fun.asgc.neutrino.core.bean.SimpleBeanFactory;
@@ -31,8 +32,11 @@ import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
@@ -61,7 +65,7 @@ public class ApplicationContext implements LifeCycle {
* 生命周期管理者
*/
private LifeCycleManager lifeCycleManager = LifeCycleManager.create();
private Set<Class<?>> classes = new HashSet<>();
public ApplicationContext(Environment environment) {
this.environment = environment;
@@ -72,11 +76,13 @@ public class ApplicationContext implements LifeCycle {
this.lifeCycleManager.init(() -> {
try {
GlobalConfig.setIsContainerStartup(true);
this.classes = ClassUtil.scan(environment.getScanBasePackages());
this.rootBeanFactory = new SimpleBeanFactory("rootBeanFactory");
this.applicationBeanFactory = new SimpleBeanFactory(rootBeanFactory, "applicationBeanFactory");
this.rootBeanFactory.registerBean(environment);
this.rootBeanFactory.registerBean(this);
this.rootBeanFactory.registerBean(environment.getConfig());
preLoad();
register();
List<BeanFactoryAware> beanFactoryAwareList = this.applicationBeanFactory.getBeanList(BeanFactoryAware.class);
if (CollectionUtil.notEmpty(beanFactoryAwareList)) {
@@ -95,21 +101,52 @@ public class ApplicationContext implements LifeCycle {
@Override
public void destroy() {
this.lifeCycleManager.destroy(() -> {
this.applicationBeanFactory.destroy();
log.info("应用上下文销毁");
});
}
/**
* 预加载
* @throws Exception
*/
private void preLoad() throws Exception {
for (Class<?> c : this.classes) {
if (!c.isAnnotationPresent(PreLoad.class)) {
continue;
}
Set<Method> methodSet = ReflectUtil.getDeclaredMethods(c);
if (CollectionUtil.isEmpty(methodSet)) {
continue;
}
PreLoad preLoad = c.getAnnotation(PreLoad.class);
String name = preLoad.value();
if (StringUtil.isEmpty(name)) {
continue;
}
Optional<Method> methodOptional = methodSet.stream().filter(m -> m.getName().equals(name) && Modifier.isStatic(m.getModifiers())
&& (m.getParameterCount() == 0 ||
(m.getParameterCount() == 1 && m.getParameters()[0].getType().isArray() && String.class.isAssignableFrom(m.getParameters()[0].getType().getComponentType()))))
.findFirst();
if (!methodOptional.isPresent()) {
continue;
}
Method method = methodOptional.get();
Object o = c.newInstance();
log.debug("PreLoad execute {}#{}", c.getName(), method.getName());
if (method.getParameterCount() == 0) {
method.invoke(o);
} else {
method.invoke(o, new Object[]{this.environment.getMainArgs()});
}
}
}
/**
* bean注册
* 所有的拦截器默认都是bean组件,没带Component注解时,默认是延迟加载的
*/
private void register() throws IOException, ClassNotFoundException {
Set<Class<?>> classes = ClassUtil.scan(environment.getScanBasePackages());
if (null == classes) {
classes = new HashSet<>();
}
classes.add(BeanManager.class);
classes.add(ExtensionServiceLoader.class);
applicationBeanFactory.register(classes);
@@ -120,9 +157,5 @@ public class ApplicationContext implements LifeCycle {
*/
public void run() {
init();
// List<ApplicationRunner> applicationRunnerList = this.applicationBeanFactory.getBeanList(ApplicationRunner.class);
// if (CollectionUtil.notEmpty(applicationRunnerList)) {
// applicationRunnerList.forEach(applicationRunner -> applicationRunner.run(this.environment.getMainArgs()));
// }
}
}
@@ -33,6 +33,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
@@ -89,6 +90,20 @@ public class FileUtil {
}
}
/**
* 读取文件内容
* @param path
* @return
* @throws IOException
*/
public static List<String> readContentAsStringList(String path) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(getInputStream(path)))){
return br.lines().collect(Collectors.toList());
} catch (Exception e) {
return null;
}
}
/**
* 读取字节内容
* @param path
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.bean.test5;
import fun.asgc.neutrino.core.annotation.NeutrinoApplication;
import fun.asgc.neutrino.core.context.NeutrinoLauncher;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@NeutrinoApplication
public class Launcher {
public static void main(String[] args) {
NeutrinoLauncher.run(Launcher.class, args);
}
}
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.bean.test5;
import fun.asgc.neutrino.core.annotation.PreLoad;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@PreLoad
public class PreLoad1 {
public static void preLoad(String[] args) {
System.out.println("11");
}
}
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.bean.test5;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.context.ApplicationRunner;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Order(0)
@Component
public class Runner1 implements ApplicationRunner {
@Override
public void run(String[] args) throws Exception {
System.out.println("1111");
try {
Thread.sleep(3000);
} catch (Exception e) {
//
}
System.out.println("----11111");
}
}
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.bean.test5;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.context.ApplicationRunner;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Order(1)
@Component
public class Runner2 implements ApplicationRunner {
@Override
public void run(String[] args) throws Exception {
System.out.println("2222");
}
}
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.db.template;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
public class JdbcTemplateTestForSqlite2 {
@Test
public void test1() throws ClassNotFoundException, SQLException {
Class.forName("org.sqlite.JDBC");
//建立一个数据库名zieckey.db的连接,如果不存在就在当前目录下创建之
Connection conn = DriverManager.getConnection("jdbc:sqlite:aa.db");
System.out.println(conn);
}
}
@@ -2,7 +2,7 @@ neutrino:
application:
name: neutrino-proxy-server
http:
enable: true
enable: false
port: 8080
context-path: /test
max-content-length-desc: 128K
+5
View File
@@ -20,6 +20,11 @@
<artifactId>neutrino-proxy-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
</dependency>
</dependencies>
<build>
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.base.rest;
import fun.asgc.neutrino.core.annotation.PreLoad;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.List;
/**
*
* @author: 初始化数据库
* @date: 2022/7/31
*/
@PreLoad("init")
public class DBInitialize {
private static Connection conn;
public static void init() throws Exception {
initDBStructure();
}
/**
* 初始化数据库结构
*/
private static void initDBStructure() throws Exception {
Statement stat = getOrNewConnection().createStatement();
List<String> lines = FileUtil.readContentAsStringList("classpath:/init-structure.sql");
if (CollectionUtil.isEmpty(lines)) {
return;
}
String sql = "";
for (String line : lines) {
if (StringUtil.isEmpty(line) || StringUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
continue;
}
sql += "\r\n" + line.trim();
if (sql.endsWith(";")) {
stat.executeUpdate(sql);
sql = "";
}
}
}
/**
* 获取一个数据库连接,如果数据库不存在,则会创建一个空数据库
* @return
* @throws Exception
*/
public static Connection getOrNewConnection() throws Exception {
return LockUtil.doubleCheckProcess(
() -> null == conn,
DBInitialize.class,
() -> {
Class.forName("org.sqlite.JDBC");
//建立一个数据库名data.db的连接,如果不存在就在当前目录下创建之
DBInitialize.conn = DriverManager.getConnection("jdbc:sqlite:data.db");
},
() -> conn
);
}
}
@@ -0,0 +1,19 @@
#
CREATE TABLE IF NOT EXISTS `user` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`name` varchar(50) NOT NULL,
`login_name` varchar(50) NOT NULL,
`login_password` varchar(255) NOT NULL,
`create_time` INTEGER(20) NOT NULL,
`update_time` INTEGER(20) NOT NULL
);
#license表
CREATE TABLE IF NOT EXISTS `license` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`name` varchar(50) NOT NULL,
`key` varchar(100) NOT NULL,
`user_id` INTEGER NOT NULL,
`create_time` INTEGER(20) NOT NULL,
`update_time` INTEGER(20) NOT NULL
);