bean容器重构ing.

This commit is contained in:
aoshiguchen
2022-07-02 19:24:11 +08:00
parent 24d40f9d2e
commit 9cfbcaba66
29 changed files with 1385 additions and 58 deletions
@@ -35,5 +35,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Lazy {
boolean value() default true;
}
@@ -0,0 +1,419 @@
/**
* 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;
import fun.asgc.neutrino.core.context.LifeCycle;
import fun.asgc.neutrino.core.context.LifeCycleManager;
import fun.asgc.neutrino.core.context.LifeCycleStatus;
import fun.asgc.neutrino.core.exception.BeanException;
import fun.asgc.neutrino.core.util.Assert;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.core.util.TypeUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 抽象的bean工厂
* @author: aoshiguchen
* @date: 2022/7/1
*/
@Slf4j
public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry, LifeCycle {
/**
* 父工厂
*/
private AbstractBeanFactory parent;
/**
* bean缓存
*/
protected Map<BeanIdentity, BeanWrapper> beanCache;
/**
* 互斥锁
*/
private Object mutex;
/**
* 名称
*/
private String name;
/**
* 生命周期管理
*/
private LifeCycleManager lifeCycleManager = LifeCycleManager.create();
public AbstractBeanFactory(String name) {
this(null, name);
}
public AbstractBeanFactory(AbstractBeanFactory parent, String name) {
Assert.notNull(name, "工厂名称不能为空");
this.parent = parent;
this.beanCache = new ConcurrentHashMap<>(256);
this.name = name;
if (null == parent) {
this.mutex = new Object();
} else {
this.mutex = parent.getMutex();
}
this.registerBean(this, this.name);
}
@Override
public <T> T getBean(String name, Object... args) throws BeanException {
Assert.notEmpty(name, "Bean名称不能为空!");
T bean = (null == parent) ? null : parent.getBean(name, args);
return null != bean ? bean : doGetBean(name, args);
}
@Override
public <T> T getBean(Class<T> type, Object... args) throws BeanException {
Assert.notNull(type, "Bean类型不能为空!");
T bean = (null == parent) ? null : parent.getBean(type, args);
return null != bean ? bean : doGetBean(type, args);
}
@Override
public <T> T getBeanByTypeAndName(Class<T> type, String name, Object... args) throws BeanException {
Assert.notEmpty(name, "Bean名称不能为空!");
Assert.notNull(type, "Bean类型不能为空!");
T bean = (null == parent) ? null : parent.getBeanByTypeAndName(type, name, args);
return null != bean ? bean : doGetBeanByNameAndType(name, type, args);
}
@Override
public <T> T getBean(BeanIdentity identity, Object... args) throws BeanException {
Assert.notNull(identity, "Bean的身份标识不能为空!");
return (T)getBeanByTypeAndName(identity.getType(), identity.getName(), args);
}
@Override
public <T> List<T> getBeanList(Class<T> type, Object... args) throws BeanException {
return CollectionUtil.addAll(() -> new LinkedList<>(),
null == parent ? null : parent.getBeanList(type, args),
doGetBeanList(type, args)
);
}
@Override
public boolean hasBean(Class<?> type, String name) {
boolean res = (null != parent) ? parent.hasBean(type, name) : false;
return res || doHasBean(type, name);
}
@Override
public int countBean(String name) {
int count = (null != parent) ? parent.countBean(name) : 0;
return count + doCountBean(name);
}
@Override
public int countBean(Class<?> type) {
int count = (null != parent) ? parent.countBean(type) : 0;
return count + doCountBean(type);
}
@Override
public void registerBean(Object obj) throws BeanException {
Assert.notNull(obj, "被注册的bean实例不能为空!");
String name = TypeUtil.getDefaultVariableName(obj.getClass());
registerBean(obj, name);
}
/**
* 手动new出来的bean注册进来,视为已经初始化了
* @param obj
* @param name
* @throws BeanException
*/
@Override
public void registerBean(Object obj, String name) throws BeanException {
Assert.notNull(obj, "被注册的bean实例不能为空!");
Assert.notNull(obj, "被注册的bean名称不能为空!");
synchronized (mutex) {
if (hasBean(obj.getClass(), name)) {
throw new BeanException(String.format("Bean[type:%s name:%s] 已存在,不能重复注册!", obj.getClass().getName(), name));
}
addBean(new BeanWrapper()
.setType(obj.getClass())
.setName(name)
.setInstance(obj)
.setStatus(BeanStatus.INIT)
);
}
}
@Override
public void registerBean(Class<?> type) throws BeanException {
registerBean(type, TypeUtil.getDefaultVariableName(type));
}
@Override
public void registerBean(Class<?> type, String name) throws BeanException {
synchronized (mutex) {
if (hasBean(type, name)) {
throw new BeanException(String.format("Bean[type:%s name:%s] 已存在,不能重复注册!", type.getName(), name));
}
addBean(type, name);
}
}
private <T> T doGetBean(String name, Object... args) throws BeanException {
List<BeanWrapper> beanList = findBeanList(name);
if (CollectionUtil.isEmpty(beanList)) {
return null;
} else if (beanList.size() > 1) {
throw new BeanException(String.format("Bean[name:%s] 存在多个实例!", name));
}
return getOrNew(beanList.get(0));
}
private <T> T doGetBean(Class<T> type, Object... args) throws BeanException {
List<BeanWrapper> beanList = findBeanList(type);
if (CollectionUtil.isEmpty(beanList)) {
return null;
} else if (beanList.size() > 1) {
throw new BeanException(String.format("Bean[type:%s] 存在多个实例!", type));
}
return getOrNew(beanList.get(0));
}
private <T> T doGetBeanByNameAndType(String name, Class<T> type, Object... args) throws BeanException {
BeanWrapper bean = findBean(type, name);
if (null == bean) {
return null;
}
return getOrNew(bean);
}
private <T> List<T> doGetBeanList(Class<T> type, Object... args) throws BeanException {
List<BeanWrapper> beanList = findBeanList(type);
if (CollectionUtil.isEmpty(beanList)) {
return null;
}
return getOrNew(beanList);
}
private boolean doHasBean(Class<?> type, String name) {
return beanCache.containsKey(new BeanIdentity(name, type));
}
private int doCountBean(String name) {
return beanCache.keySet().stream().filter(e -> e.getName().equals(name)).collect(Collectors.counting()).intValue();
}
private int doCountBean(Class<?> type) {
return beanCache.keySet().stream().filter(e -> type.isAssignableFrom(e.getType())).collect(Collectors.counting()).intValue();
}
public Object getMutex() {
return mutex;
}
/**
* 查找bean
* @param name
* @return
*/
private List<BeanWrapper> findBeanList(String name) {
Assert.notNull(name, "bean的名称不能为空!");
List<BeanWrapper> beanList = new LinkedList<>();
for (BeanIdentity identity : beanCache.keySet()) {
if (identity.getName().equals(name)) {
beanList.add(beanCache.get(identity));
}
}
return beanList;
}
/**
* 查找bean
* @param type
* @return
*/
private List<BeanWrapper> findBeanList(Class<?> type) {
Assert.notNull(type, "bean的类型不能为空!");
List<BeanWrapper> beanList = new LinkedList<>();
for (BeanIdentity identity : beanCache.keySet()) {
if (type.isAssignableFrom(identity.getType())) {
beanList.add(beanCache.get(identity));
}
}
return beanList;
}
/**
* 查找bean
* @param type
* @param name
* @return
*/
private BeanWrapper findBean(Class<?> type, String name) {
Assert.notNull(type, "bean的类型不能为空!");
Assert.notNull(name, "bean的名称不能为空!");
return beanCache.get(new BeanIdentity(name, type));
}
/**
* 新增一个bean
* @param bean
*/
protected void addBean(BeanWrapper bean) {
beanCache.put(new BeanIdentity(bean.getName(), bean.getType()), bean);
}
@Override
public void init() {
lifeCycleManager.init(() -> {
if (null != parent) {
parent.init();
}
if (CollectionUtil.notEmpty(beanCache)) {
beanCache.values().stream().filter(b -> BeanStatus.INJECT == b.getStatus()).forEach(bean -> bean.init());
}
log.info("bean工厂[{}]初始化.", getName());
});
}
@Override
public void destroy() {
lifeCycleManager.destroy(() -> {
if (null != parent) {
parent.destroy();
}
if (CollectionUtil.notEmpty(beanCache)) {
beanCache.values().stream().filter(b -> BeanStatus.DESTROY != b.getStatus()).forEach(bean -> bean.destroy());
}
log.info("bean工厂[{}]销毁.", getName());
});
}
/**
* 获取或创建实例
* @param beanList
* @param <T>
* @return
* @throws BeanException
*/
protected <T> List<T> getOrNew(List<BeanWrapper> beanList) throws BeanException {
List<T> list = new LinkedList<>();
if (CollectionUtil.isEmpty(beanList)) {
return list;
}
for (BeanWrapper bean : beanList) {
T instance = getOrNew(bean);
if (null == instance) {
throw new BeanException(String.format("Bean[type:%s name:%s]实例化失败!", bean.getType().getName(), bean.getName()));
}
list.add(instance);
}
return list;
}
/**
* 获取名称
* @return
*/
public String getName() {
return name;
}
/**
* 获取生命周期状态
* @return
*/
public LifeCycleStatus getLifeCycleStatus() {
return lifeCycleManager.getStatus();
}
/**
* 获取生命周期管理对象
* @return
*/
public LifeCycleManager getLifeCycleManager() {
return lifeCycleManager;
}
/**
* 新增一个bean
* @param type
* @param name
*/
protected abstract void addBean(Class<?> type, String name);
/**
* 获取或创建实例
* @param bean
* @param <T>
* @return
*/
protected <T> T getOrNew(BeanWrapper bean) throws BeanException {
return (T)LockUtil.doubleCheckProcess(
() -> !(BeanStatus.INIT == bean.getStatus() || BeanStatus.RUNNING == bean.getStatus()),
bean,
() -> {
if (BeanStatus.REGISTER == bean.getStatus()) {
dependencyCheck(bean);
}
if (BeanStatus.DEPENDENCY_CHECKING == bean.getStatus()) {
newInstance(bean);
}
if (BeanStatus.INSTANCE == bean.getStatus()) {
inject(bean);
}
if (BeanStatus.INJECT == bean.getStatus()) {
bean.init();
}
},
() -> bean.getInstance()
);
}
/**
* 依赖关系检测
* @param bean
* @return
* @throws BeanException
*/
protected abstract boolean dependencyCheck(BeanWrapper bean) throws BeanException;
/**
* 实例化
* @param bean
* @param <T>
* @return
* @throws BeanException
*/
protected abstract <T> T newInstance(BeanWrapper bean) throws BeanException;
/**
* 注入
* @param bean
* @return
* @throws BeanException
*/
protected abstract boolean inject(BeanWrapper bean) throws BeanException;
}
@@ -0,0 +1,84 @@
/**
* 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;
import fun.asgc.neutrino.core.exception.BeanException;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/7/1
*/
public interface BeanFactory {
/**
* 尝试根据名称获取bean
* @param name
* @param args
* @return
* @throws BeanException
*/
<T> T getBean(String name, Object... args) throws BeanException;
/**
* 尝试根据类型获取bean
* @param type
* @param args
* @param <T>
* @return
* @throws BeanException
*/
<T> T getBean(Class<T> type, Object... args) throws BeanException;
/**
* 尝试根据Bean身份标识获取bean
* @param identity
* @param args
* @param <T>
* @return
* @throws BeanException
*/
<T> T getBean(BeanIdentity identity, Object... args) throws BeanException;
/**
* 根据类型+名称获取bean
* @param type
* @param name
* @param args
* @param <T>
* @return
* @throws BeanException
*/
<T> T getBeanByTypeAndName(Class<T> type, String name, Object... args) throws BeanException;
/**
* 尝试根据类型获取bean
* @param type
* @param args
* @param <T>
* @return
* @throws BeanException
*/
<T> List<T> getBeanList(Class<T> type, Object... args) throws BeanException;
}
@@ -0,0 +1,93 @@
/**
* 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;
import fun.asgc.neutrino.core.util.Assert;
/**
* 用于标识bean的身份
*
* 此处用名称+类型作为bean的唯一标识
*
* @author: aoshiguchen
* @date: 2022/7/1
*/
public class BeanIdentity implements Identity {
/**
* 名称
*/
private String name;
/**
* 类型
*/
private Class<?> type;
/**
* hashCode
*/
private int identityHashCode;
public BeanIdentity(String name, Class<?> type) {
Assert.notEmpty(name, "名称不能为空!");
Assert.notNull(type, "类型不能为空!");
this.name = name;
this.type = type;
this.identityHashCode = System.identityHashCode(name) + System.identityHashCode(type);
}
/**
* 获取名称
* @return
*/
public String getName() {
return this.name;
}
/**
* 获取类型
* @return
*/
public Class<?> getType() {
return this.type;
}
@Override
public boolean isOnly() {
return Boolean.TRUE;
}
@Override
public boolean equals(Object obj) {
if (null == obj) {
return false;
}
if (!(obj instanceof BeanIdentity)) {
return false;
}
BeanIdentity beanIdentity = (BeanIdentity)obj;
return this.name.equals(beanIdentity.getName()) && this.type.equals(beanIdentity.getType());
}
@Override
public int hashCode() {
return identityHashCode;
}
}
@@ -0,0 +1,84 @@
/**
* 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;
import fun.asgc.neutrino.core.exception.BeanException;
/**
* bean注册表
* @author: aoshiguchen
* @date: 2022/7/1
*/
public interface BeanRegistry {
/**
* 注册bean
* @param obj
* @throws BeanException
*/
void registerBean(Object obj) throws BeanException;
/**
* 注册bean
* @param obj
* @param name
* @throws BeanException
*/
void registerBean(Object obj, String name) throws BeanException;
/**
* 注册bean
* @param type
* @throws BeanException
*/
void registerBean(Class<?> type) throws BeanException;
/**
* 注册bean
* @param type
* @param name
* @throws BeanException
*/
void registerBean(Class<?> type, String name) throws BeanException;
/**
* 判断是否包含此bean
* @param type
* @param name
* @return
*/
boolean hasBean(Class<?> type, String name);
/**
* 查询bean容器中有多少个叫该名称的bean
* @param name
* @return
*/
int countBean(String name);
/**
* 查询bean容器中有多少个该类型的bean
* @param type
* @return
*/
int countBean(Class<?> type);
}
@@ -0,0 +1,55 @@
/**
* 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;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Bean的几种状态
* @author: aoshiguchen
* @date: 2022/7/2
*/
@Getter
@AllArgsConstructor
public enum BeanStatus {
REGISTER(1, "已注册"),
DEPENDENCY_CHECKING(2, "依赖关系检测完成"),
INSTANCE(3, "已实例化"),
INJECT(4, "已完成注入"),
INIT(5, "已初始化"),
RUNNING(6, "运行中"),
DESTROY(7, "已销毁");
private static final Map<Integer, BeanStatus> cache = Stream.of(BeanStatus.values()).collect(Collectors.toMap(BeanStatus::getStatus, Function.identity()));
private Integer status;
private String desc;
public static BeanStatus of(Integer status) {
return cache.get(status);
}
}
@@ -20,22 +20,23 @@
* SOFTWARE.
*/
package fun.asgc.neutrino.core.context;
package fun.asgc.neutrino.core.bean;
import fun.asgc.neutrino.core.annotation.*;
import fun.asgc.neutrino.core.aop.Aop;
import fun.asgc.neutrino.core.container.LifeCycle;
import fun.asgc.neutrino.core.context.LifeCycle;
import fun.asgc.neutrino.core.container.BeanContainer;
import fun.asgc.neutrino.core.context.ApplicationConfig;
import fun.asgc.neutrino.core.context.ApplicationContext;
import fun.asgc.neutrino.core.context.Environment;
import fun.asgc.neutrino.core.util.*;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.stream.Stream;
/**
*
@@ -45,14 +46,16 @@ import java.util.stream.Stream;
@Slf4j
@Accessors(chain = true)
@Data
public class Bean implements LifeCycle {
public class BeanWrapper implements LifeCycle {
private String name;
private Class<?> clazz;
private Class<?> type;
private Object instance;
private Component component;
private int order;
private boolean isBoot;
private volatile boolean isInit;
private BeanStatus status;
private boolean isLazy;
public boolean hasInstance() {
return null != instance;
@@ -68,14 +71,14 @@ public class Bean implements LifeCycle {
}
isInit = true;
Set<Method> methods = ReflectUtil.getMethods(clazz);
Set<Method> methods = ReflectUtil.getMethods(type);
if (CollectionUtil.notEmpty(methods)) {
for (Method method : methods) {
if (method.isAnnotationPresent(Init.class) && method.getParameters().length == 0) {
try {
method.invoke(instance);
} catch (Exception e) {
log.error(String.format("初始化方法执行异常 class:%s method:%s", clazz.getName(), method.getName()), e);
log.error(String.format("初始化方法执行异常 class:%s method:%s", type.getName(), method.getName()), e);
}
}
}
@@ -87,14 +90,14 @@ public class Bean implements LifeCycle {
if (!hasInstance()) {
return;
}
Set<Method> methods = ReflectUtil.getMethods(clazz);
Set<Method> methods = ReflectUtil.getMethods(type);
if (CollectionUtil.notEmpty(methods)) {
for (Method method : methods) {
if (method.isAnnotationPresent(Destroy.class) && method.getParameters().length == 0) {
try {
method.invoke(instance);
} catch (Exception e) {
log.error(String.format("销毁方法执行异常 class:%s method:%s", clazz.getName(), method.getName()), e);
log.error(String.format("销毁方法执行异常 class:%s method:%s", type.getName(), method.getName()), e);
}
}
}
@@ -116,14 +119,14 @@ public class Bean implements LifeCycle {
() -> {
try {
// 暂时先只支持yml配置
Configuration configuration = clazz.getAnnotation(Configuration.class);
Configuration configuration = type.getAnnotation(Configuration.class);
if (null != configuration) {
instance = ConfigUtil.getYmlConfig(clazz);
} else if (ClassUtil.isInterface(clazz)) {
instance = Aop.get(clazz);
instance = ConfigUtil.getYmlConfig(type);
} else if (ClassUtil.isInterface(type)) {
instance = Aop.get(type);
} else {
// 由编码规避没有无参构造器的问题
instance = clazz.newInstance();
instance = type.newInstance();
}
} catch (Exception e) {
// ignore
@@ -134,7 +137,7 @@ public class Bean implements LifeCycle {
}
private void inject(ApplicationContext context) {
Set<Method> methods = ReflectUtil.getMethods(clazz);
Set<Method> methods = ReflectUtil.getMethods(type);
if (CollectionUtil.notEmpty(methods)) {
methods.stream().forEach(method -> {
fun.asgc.neutrino.core.annotation.Bean bean = method.getAnnotation(fun.asgc.neutrino.core.annotation.Bean.class);
@@ -153,8 +156,8 @@ public class Bean implements LifeCycle {
log.error("bean 实例不能为空!");
return;
}
context.getBeanContainer().addBean(new Bean()
.setClazz(obj.getClass())
context.getBeanContainer().addBean(new BeanWrapper()
.setType(obj.getClass())
.setBoot(false)
.setComponent(null)
.setInstance(obj)
@@ -167,7 +170,7 @@ public class Bean implements LifeCycle {
}
});
}
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(clazz);
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(type);
if (CollectionUtil.notEmpty(fieldSet)) {
fieldSet.forEach(field -> {
Autowired autowired = field.getAnnotation(Autowired.class);
@@ -184,17 +187,17 @@ public class Bean implements LifeCycle {
ReflectUtil.setFieldValue(field, instance, context);
} else {
Class<?> autowiredType = field.getType();
Bean autowiredBean = null;
BeanWrapper autowiredBean = null;
if (StringUtil.isEmpty(autowired.value())) {
autowiredBean = context.getBeanContainer().getBean(autowiredType);
} else {
autowiredBean = context.getBeanContainer().getBean(autowired.value());
}
if (null == autowiredBean) {
throw new RuntimeException(String.format("类 %s 自动装配字段:%s 依赖bean不存在!", clazz.getName(), field.getName()));
throw new RuntimeException(String.format("类 %s 自动装配字段:%s 依赖bean不存在!", type.getName(), field.getName()));
}
if (autowiredBean.isDependOn(clazz)) {
throw new RuntimeException(String.format("类[%s]与类[%s]存在循环依赖!", clazz.getName(), field.getType().getName()));
if (autowiredBean.isDependOn(type)) {
throw new RuntimeException(String.format("类[%s]与类[%s]存在循环依赖!", type.getName(), field.getType().getName()));
}
autowiredBean.newInstance(context);
ReflectUtil.setFieldValue(field, instance, autowiredBean.getInstance());
@@ -204,7 +207,7 @@ public class Bean implements LifeCycle {
}
public boolean isLazy() {
Lazy lazy = ClassUtil.getAnnotation(clazz, Lazy.class);
Lazy lazy = ClassUtil.getAnnotation(type, Lazy.class);
return null != lazy;
}
@@ -212,7 +215,7 @@ public class Bean implements LifeCycle {
if (null == target) {
return false;
}
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(clazz);
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(type);
if (CollectionUtil.isEmpty(fieldSet)) {
return false;
}
@@ -227,4 +230,8 @@ public class Bean implements LifeCycle {
}
return false;
}
public void run() {
}
}
@@ -0,0 +1,40 @@
/**
* 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;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author: aoshiguchen
* @date: 2022/7/2
*/
public class ClassScanner {
private Set<Class<?>> classes = new HashSet<>();
private List<String> scanBasePackages;
public ClassScanner(List<String> scanBasePackages) {
this.scanBasePackages = scanBasePackages;
}
}
@@ -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.bean;
/**
* Identity 用于标识一个身份。
*
* 当`isOnly()`为true时,该标识是一个唯一标识。
*
* 如:身份证、财富、年龄都可以作为人的身份象征,但只有身份证是唯一标识。
* 这个唯一性取决与理论上的定义,而非实际数据。
* 例如有三个人,年龄分别是18、19、20,此时对于这三人而言,年龄是唯一的,但年龄这个标识我们仍然认为是非唯一标识。
* 除非在特定场景下,这些数据固定不变、或者确保以后新增的数据也不会打破这一设定。
*
* @author: aoshiguchen
* @date: 2022/7/1
*/
public interface Identity {
/**
* 是否唯一标识
* @return
*/
boolean isOnly();
}
@@ -0,0 +1,97 @@
/**
* 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;
import fun.asgc.neutrino.core.annotation.Lazy;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.exception.BeanException;
import fun.asgc.neutrino.core.runner.ApplicationRunner;
import fun.asgc.neutrino.core.util.ClassUtil;
import fun.asgc.neutrino.core.util.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* @author: 一个简单的bean工厂实现
* @date: 2022/7/2
*/
@Slf4j
public class SimpleBeanFactory extends AbstractBeanFactory {
public SimpleBeanFactory(String name) {
super(name);
}
public SimpleBeanFactory(AbstractBeanFactory parent, String name) {
super(parent, name);
}
@Override
protected void addBean(Class<?> type, String name) {
log.debug("addBean[type:{} name:{}]", type.getName(), name);
BeanWrapper beanWrapper = new BeanWrapper()
.setType(type)
.setName(name)
.setLazy(Boolean.FALSE)
.setOrder(Integer.MAX_VALUE)
.setStatus(BeanStatus.REGISTER);
Lazy lazy = ClassUtil.getAnnotation(type, Lazy.class);
if (null != lazy) {
beanWrapper.setLazy(lazy.value());
}
Order order = ClassUtil.getAnnotation(type, Order.class);
if (null != order) {
beanWrapper.setOrder(order.value());
}
addBean(beanWrapper);
}
@Override
protected boolean dependencyCheck(BeanWrapper bean) throws BeanException {
return false;
}
@Override
protected <T> T newInstance(BeanWrapper bean) throws BeanException {
return null;
}
@Override
protected boolean inject(BeanWrapper bean) throws BeanException {
return false;
}
@Override
public void init() {
List<BeanWrapper> beanWrapperList = beanCache.values().stream()
.filter(b -> b.getStatus().getStatus() < BeanStatus.INIT.getStatus())
.filter(b -> ApplicationRunner.class.isAssignableFrom(b.getType()) || !b.isLazy() || b.getOrder() <= 0)
.collect(Collectors.toList());
if (CollectionUtil.notEmpty(beanWrapperList)) {
getOrNew(beanWrapperList);
}
super.init();
}
}
@@ -29,6 +29,4 @@ package fun.asgc.neutrino.core.container;
*/
public interface ApplicationContainer extends Container {
}
@@ -22,7 +22,7 @@
package fun.asgc.neutrino.core.container;
import fun.asgc.neutrino.core.context.Bean;
import fun.asgc.neutrino.core.bean.BeanWrapper;
import java.util.List;
@@ -52,24 +52,24 @@ public interface BeanContainer extends Container {
* @param clazz
* @return
*/
Bean getBean(Class<?> clazz);
BeanWrapper getBean(Class<?> clazz);
/**
* 获取bean实例
* @param name
* @return
*/
Bean getBean(String name);
BeanWrapper getBean(String name);
/**
* 获取bean集合
* @return
*/
List<Bean> beanList();
List<BeanWrapper> beanList();
/**
* 添加bean
* @param bean
*/
void addBean(Bean bean);
void addBean(BeanWrapper bean);
}
@@ -22,6 +22,8 @@
package fun.asgc.neutrino.core.container;
import fun.asgc.neutrino.core.context.LifeCycle;
/**
*
* @author: aoshiguchen
@@ -67,7 +67,7 @@ public class DefaultApplicationContainer implements ApplicationContainer {
this.beanContainer.beanList().forEach(bean -> {
if (bean.isBoot()) {
if (bean.hasInstance()) {
if (ApplicationRunner.class.isAssignableFrom(bean.getClazz())) {
if (ApplicationRunner.class.isAssignableFrom(bean.getType())) {
ApplicationRunner runner = (ApplicationRunner)bean.getInstance();
runner.run(environment.getMainArgs());
}
@@ -25,7 +25,7 @@ package fun.asgc.neutrino.core.container;
import com.google.common.collect.Lists;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.context.Bean;
import fun.asgc.neutrino.core.bean.BeanWrapper;
import fun.asgc.neutrino.core.cache.Cache;
import fun.asgc.neutrino.core.cache.MemoryCache;
import fun.asgc.neutrino.core.context.Environment;
@@ -49,9 +49,9 @@ import java.util.List;
public class DefaultBeanContainer implements BeanContainer {
private Environment environment;
private ClassContainer classContainer;
private Cache<String, Bean> nameBeanCache;
private Cache<Class<?>, Bean> classBeanCache;
private List<Bean> beans;
private Cache<String, BeanWrapper> nameBeanCache;
private Cache<Class<?>, BeanWrapper> classBeanCache;
private List<BeanWrapper> beans;
public DefaultBeanContainer(Environment environment) {
this.environment = environment;
@@ -72,12 +72,12 @@ public class DefaultBeanContainer implements BeanContainer {
}
@Override
public Bean getBean(Class<?> clazz) {
public BeanWrapper getBean(Class<?> clazz) {
return classBeanCache.get(clazz);
}
@Override
public Bean getBean(String name) {
public BeanWrapper getBean(String name) {
return nameBeanCache.get(name);
}
@@ -96,8 +96,8 @@ public class DefaultBeanContainer implements BeanContainer {
orderValue = order.value();
}
addBean(new Bean()
.setClazz(clazz)
addBean(new BeanWrapper()
.setType(clazz)
.setName(name)
.setComponent(component)
.setOrder(orderValue)
@@ -107,7 +107,7 @@ public class DefaultBeanContainer implements BeanContainer {
if (!classBeanCache.isEmpty()) {
beans = Lists.newArrayList(classBeanCache.values());
Collections.sort(beans, Comparator.comparingInt(Bean::getOrder));
Collections.sort(beans, Comparator.comparingInt(BeanWrapper::getOrder));
}
log.info("bean容器初始化完成");
@@ -120,21 +120,21 @@ public class DefaultBeanContainer implements BeanContainer {
}
@Override
public void addBean(Bean bean) {
public void addBean(BeanWrapper bean) {
if (null == bean) {
return;
}
// TODO 暂时由编码时规避名字冲突
if (ApplicationRunner.class.isAssignableFrom(bean.getClazz())) {
if (ApplicationRunner.class.isAssignableFrom(bean.getType())) {
bean.setOrder(Integer.MIN_VALUE);
bean.setBoot(true);
}
classBeanCache.set(bean.getClazz(), bean);
classBeanCache.set(bean.getType(), bean);
nameBeanCache.set(bean.getName(), bean);
}
@Override
public List<Bean> beanList() {
public List<BeanWrapper> beanList() {
return beans;
}
}
@@ -22,10 +22,22 @@
package fun.asgc.neutrino.core.context;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.aop.interceptor.ExceptionHandler;
import fun.asgc.neutrino.core.aop.interceptor.Filter;
import fun.asgc.neutrino.core.aop.interceptor.Interceptor;
import fun.asgc.neutrino.core.aop.interceptor.ResultAdvice;
import fun.asgc.neutrino.core.bean.SimpleBeanFactory;
import fun.asgc.neutrino.core.container.BeanContainer;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.core.runner.ApplicationRunner;
import fun.asgc.neutrino.core.util.*;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
*
@@ -34,7 +46,8 @@ import lombok.experimental.Accessors;
*/
@Accessors(chain = true)
@Data
public class ApplicationContext {
@Slf4j
public class ApplicationContext implements LifeCycle {
/**
* 应用环境
@@ -48,4 +61,92 @@ public class ApplicationContext {
* bean容器
*/
private BeanContainer beanContainer;
/**
* 根Bean工厂
*/
private SimpleBeanFactory rootBeanFactory;
/**
* bean工厂
*/
private SimpleBeanFactory applicationBeanFactory;
/**
* 生命周期管理者
*/
private LifeCycleManager lifeCycleManager = LifeCycleManager.create();
public ApplicationContext() {
}
public ApplicationContext(Environment environment) {
this.environment = environment;
}
@Override
public synchronized void init() {
this.lifeCycleManager.init(() -> {
try {
this.rootBeanFactory = new SimpleBeanFactory("rootBeanFactory");
this.applicationBeanFactory = new SimpleBeanFactory(rootBeanFactory, "applicationBeanFactory");
this.rootBeanFactory.registerBean(environment, "rootEnvironment");
this.rootBeanFactory.registerBean(this, "rootApplicationContext");
this.rootBeanFactory.registerBean(environment.getConfig(), "rootApplicationConfig");
register();
this.applicationBeanFactory.init();
// TODO 后面优化掉这种不安全的BeanManager
BeanManager.setContext(this);
} catch (Exception e) {
log.error("应用上下文初始化异常!", e);
System.exit(-1);
}
log.info("应用上下文初始化完成");
});
}
@Override
public void destroy() {
this.lifeCycleManager.destroy(() -> {
this.applicationBeanFactory.destroy();
log.info("应用上下文销毁");
});
}
/**
* bean注册
* 所有的拦截器默认都是bean组件,没带Component注解时,默认是延迟加载的
*/
private void register() throws IOException, ClassNotFoundException {
Set<Class<?>> classes = ClassUtil.scan(environment.getScanBasePackages());
if (CollectionUtil.isEmpty(classes)) {
return;
}
classes.stream()
.filter(item -> ClassUtil.isAnnotateWith(item, Component.class)
|| Interceptor.class.isAssignableFrom(item)
|| Filter.class.isAssignableFrom(item)
|| ExceptionHandler.class.isAssignableFrom(item)
|| ResultAdvice.class.isAssignableFrom(item)
)
.forEach(clazz -> {
String beanName = TypeUtil.getDefaultVariableName(clazz);
Component component = ClassUtil.getAnnotation(clazz, Component.class);
if (null != component && StringUtil.notEmpty(component.value())) {
beanName = component.value();
}
this.applicationBeanFactory.registerBean(clazz, beanName);
});
}
/**
* 应用上下文启动
*/
public void run() {
init();
List<ApplicationRunner> applicationRunnerList = this.applicationBeanFactory.getBeanList(ApplicationRunner.class);
if (CollectionUtil.notEmpty(applicationRunnerList)) {
applicationRunnerList.forEach(applicationRunner -> applicationRunner.run(this.environment.getMainArgs()));
}
}
}
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
package fun.asgc.neutrino.core.container;
package fun.asgc.neutrino.core.context;
/**
*
@@ -0,0 +1,69 @@
/**
* 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.context;
import fun.asgc.neutrino.core.base.CodeBlock;
/**
*
* @author: 生命周期管理
* @date: 2022/7/2
*/
public class LifeCycleManager {
/**
* 生命周期状态
*/
private LifeCycleStatus status;
private LifeCycleManager() {
this.status = LifeCycleStatus.CREATE;
}
public synchronized void init(CodeBlock codeBlock) {
if (this.status == LifeCycleStatus.CREATE) {
codeBlock.execute();
this.status = LifeCycleStatus.INIT;
}
}
public synchronized void run(CodeBlock codeBlock) {
if (this.status == LifeCycleStatus.INIT) {
codeBlock.execute();
this.status = LifeCycleStatus.RUN;
}
}
public synchronized void destroy(CodeBlock codeBlock) {
if (this.status != LifeCycleStatus.DESTROY) {
codeBlock.execute();
this.status = LifeCycleStatus.DESTROY;
}
}
public static LifeCycleManager create() {
return new LifeCycleManager();
}
public LifeCycleStatus getStatus() {
return status;
}
}
@@ -0,0 +1,42 @@
/**
* 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.context;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
* @author: 生命周期状态
* @date: 2022/7/2
*/
@Getter
@AllArgsConstructor
public enum LifeCycleStatus {
CREATE(1, "已创建"),
INIT(2, "已初始化"),
RUN(3, "运行"),
DESTROY(4, "已销毁");
private Integer status;
private String desc;
}
@@ -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.exception;
/**
*
* @author: aoshiguchen
* @date: 2022/7/1
*/
public class BeanException extends InternalException {
public BeanException(String message) {
super(message);
}
public BeanException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -33,4 +33,7 @@ public class InternalException extends RuntimeException {
super(message);
}
public InternalException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -28,6 +28,7 @@ import fun.asgc.neutrino.core.constant.MetaDataConstant;
import fun.asgc.neutrino.core.container.ApplicationContainer;
import fun.asgc.neutrino.core.container.DefaultApplicationContainer;
import fun.asgc.neutrino.core.context.ApplicationConfig;
import fun.asgc.neutrino.core.context.ApplicationContext;
import fun.asgc.neutrino.core.context.Environment;
import fun.asgc.neutrino.core.util.*;
import lombok.extern.slf4j.Slf4j;
@@ -64,9 +65,15 @@ public class NeutrinoLauncher {
stopWatch.start();
environmentInit();
this.applicationContainer = new DefaultApplicationContainer(environment);
// this.applicationContainer = new DefaultApplicationContainer(environment);
// SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> {
// this.applicationContainer.destroy();
// log.info("Application already stop.");
// });
ApplicationContext context = new ApplicationContext(environment);
context.run();
SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> {
this.applicationContainer.destroy();
context.destroy();
log.info("Application already stop.");
});
@@ -204,6 +204,12 @@ public abstract class Assert {
}
}
public static void notEmpty(String s, String message) {
if (StringUtil.isEmpty(s)) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param array
@@ -25,13 +25,11 @@ package fun.asgc.neutrino.core.util;
import fun.asgc.neutrino.core.container.BeanContainer;
import fun.asgc.neutrino.core.context.ApplicationConfig;
import fun.asgc.neutrino.core.context.ApplicationContext;
import fun.asgc.neutrino.core.context.Bean;
import fun.asgc.neutrino.core.bean.BeanWrapper;
import fun.asgc.neutrino.core.context.Environment;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -64,7 +62,7 @@ public class BeanManager {
return context;
} else {
if (null != context.getBeanContainer()) {
Bean bean = context.getBeanContainer().getBean(name);
BeanWrapper bean = context.getBeanContainer().getBean(name);
if (null != bean) {
if (!bean.hasInstance()) {
bean.newInstance(context);
@@ -90,7 +88,7 @@ public class BeanManager {
return (T)context;
} else {
if (null != context.getBeanContainer()) {
Bean bean = context.getBeanContainer().getBean(clazz);
BeanWrapper bean = context.getBeanContainer().getBean(clazz);
if (null != bean) {
if (!bean.hasInstance()) {
bean.newInstance(context);
@@ -113,7 +111,7 @@ public class BeanManager {
return null;
}
return context.getBeanContainer().beanList().stream()
.map(Bean::getClazz)
.map(BeanWrapper::getType)
.filter(item -> superClass.isAssignableFrom(item))
.map(item -> (T)getBean(item))
.filter(Objects::nonNull)
@@ -25,6 +25,7 @@ package fun.asgc.neutrino.core.util;
import org.apache.commons.lang3.ObjectUtils;
import java.util.*;
import java.util.function.Supplier;
/**
*
@@ -60,6 +61,11 @@ public class CollectionUtil {
return !isEmpty(collection);
}
public static boolean notEmpty(Map map) {
return !isEmpty(map);
}
/**
*
* @param source
@@ -338,4 +344,21 @@ public class CollectionUtil {
}
return elements.toArray(array);
}
/**
* 将另一个集合的内容添加到指定集合中
* @param supplier
* @param list
*/
public static <T> List<T> addAll(Supplier<List<T>> supplier, List<T> ...list) {
List<T> res = supplier.get();
if (ArrayUtil.notEmpty(list)) {
for (List<T> l : list) {
if (null != l && CollectionUtil.notEmpty(l)) {
res.addAll(l);
}
}
}
return res;
}
}
@@ -0,0 +1,54 @@
/**
* 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.util;
import java.util.function.Supplier;
/**
* 函数工具
* @author: aoshiguchen
* @date: 2022/7/1
*/
public class FunctionUtil {
/**
* 获取第一个非空值
* @param suppliers
* @param <T>
* @return
*/
public static <T> T getFirstNotNull(Supplier<T> ...suppliers) {
T res;
if (ArrayUtil.notEmpty(suppliers)) {
for (Supplier<T> supplier : suppliers) {
if (null != supplier) {
res = supplier.get();
if (null != res) {
return res;
}
}
}
}
return null;
}
}
@@ -39,4 +39,10 @@ public class Dog {
public String say(String msg) {
return "狗说:" + msg;
}
// static 测试static方法
public int calc(int x, int y) {
System.out.println("计算 " + x + " + " + "y");
return x + y;
}
}
@@ -54,4 +54,10 @@ public class Test1 {
System.out.println(cat.calc(10, 6));
}
@Test
public void dogCalc() {
Dog dog = Aop.get(Dog.class);
System.out.println(dog.calc(1, 2));
}
}
@@ -0,0 +1,51 @@
/**
* 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;
import fun.asgc.neutrino.core.aop.Animal;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author: aoshiguchen
* @date: 2022/7/1
*/
public class BeanIdentityTest {
@Test
public void test1() {
System.out.println(new BeanIdentity("animal", Animal.class).equals(new BeanIdentity("animal", Animal.class)));
System.out.println(new BeanIdentity("animal", Animal.class) == new BeanIdentity("animal", Animal.class));
}
@Test
public void test2() {
Map<BeanIdentity, String> map = new HashMap<>();
map.put(new BeanIdentity("1", String.class), "1");
map.put(new BeanIdentity("1", String.class), "2");
System.out.println(map);
}
}