bean容器重构,支持按照名字、类型、名字+类型三种方式注入.

This commit is contained in:
aoshiguchen
2022-07-04 17:47:38 +08:00
parent 1429c78278
commit 2e726b6513
29 changed files with 833 additions and 106 deletions
@@ -22,6 +22,8 @@
package fun.asgc.neutrino.core.annotation;
import fun.asgc.neutrino.core.bean.BeanMatchMode;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,4 +38,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
String value() default "";
BeanMatchMode matchMode() default BeanMatchMode.ByTypeName;
Class<?>[] parameterTypes() default {};
}
@@ -38,17 +38,12 @@ public class Aop {
private static ProxyStrategy proxyStrategy = ProxyStrategy.AUTO;
private static final Cache<Class<?>, Object> proxyBeanCache = new MemoryCache<>();
public static <T> T get(Class<T> clazz) {
try {
return (T)LockUtil.doubleCheckProcess(() -> !proxyBeanCache.containsKey(clazz),
clazz,
() -> proxyBeanCache.set(clazz, getProxyFactory(clazz).get(clazz)),
() -> proxyBeanCache.get(clazz)
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
public static <T> T get(Class<T> clazz) throws Exception {
return (T)LockUtil.doubleCheckProcess(() -> !proxyBeanCache.containsKey(clazz),
clazz,
() -> proxyBeanCache.set(clazz, getProxyFactory(clazz).get(clazz)),
() -> proxyBeanCache.get(clazz)
);
}
/**
@@ -43,7 +43,7 @@ public class InnerGlobalInterceptor implements Interceptor {
private static final InterceptorWrapper interceptorWrapper = new InterceptorWrapper(InnerGlobalInterceptor.class.getSimpleName());
public InnerGlobalInterceptor() {
System.out.println("aaaaa");
}
@Override
@@ -49,14 +49,10 @@ public class AsgcProxyFactory implements ProxyFactory {
private ProxyClassLoader classLoader = new ProxyClassLoader();
@Override
public <T> T get(Class<T> clazz) {
public <T> T get(Class<T> clazz) throws Exception {
Assert.notNull(clazz, "被代理类不能为空!");
Assert.isTrue(canProxy(clazz), String.format("类[%s]无法被代理!", clazz.getName()));
try {
return doGet(clazz);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
return doGet(clazz);
}
@Override
@@ -114,7 +110,7 @@ public class AsgcProxyFactory implements ProxyFactory {
Method[] methods = clazz.getMethods();
if (ArrayUtil.notEmpty(methods)) {
for (Method method : methods) {
if (Modifier.isFinal(method.getModifiers())) {
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
continue;
}
Long methodId = ProxyCache.setMethod(method);
@@ -37,14 +37,10 @@ import java.util.Set;
public class JdkDynamicProxyFactory implements ProxyFactory {
@Override
public <T> T get(Class<T> clazz) {
public <T> T get(Class<T> clazz) throws Exception {
Assert.notNull(clazz, "被代理类不能为空!");
Assert.isTrue(canProxy(clazz), String.format("类[%s]无法被代理!", clazz.getName()));
try {
return doGet(clazz);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
return doGet(clazz);
}
private <T> T doGet(Class<T> clazz) throws ReflectiveOperationException {
@@ -33,7 +33,7 @@ public interface ProxyFactory {
* @param <T>
* @return
*/
<T> T get(Class<T> clazz);
<T> T get(Class<T> clazz) throws Exception;
/**
* 是否能被代理
@@ -52,6 +52,10 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* bean缓存
*/
protected Map<BeanIdentity, BeanWrapper> beanCache;
/**
* 工厂bean缓存
*/
protected Map<BeanIdentity, BeanWrapper> factoryBeanCache;
/**
* 互斥锁
*/
@@ -73,6 +77,7 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
Assert.notNull(name, "工厂名称不能为空");
this.parent = parent;
this.beanCache = new ConcurrentHashMap<>(256);
this.factoryBeanCache = new ConcurrentHashMap<>(256);
this.name = name;
if (null == parent) {
this.mutex = new Object();
@@ -89,6 +94,14 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
return null != bean ? bean : doGetBean(name, args);
}
@Override
public <T> T getBeanByName(Class<T> type, String name, Object... args) {
Assert.notEmpty(name, "Bean名称不能为空!");
T bean = (null == parent) ? null : parent.getBeanByName(type, name, args);
return null != bean ? bean : doGetBeanByName(type, name, args);
}
@Override
public <T> T getBean(Class<T> type, Object... args) throws BeanException {
Assert.notNull(type, "Bean类型不能为空!");
@@ -101,7 +114,7 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
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);
return null != bean ? bean : doGetBeanByTypeAndName(type, name, args);
}
@Override
@@ -118,6 +131,14 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
);
}
@Override
public <T> List<T> getBeanListByName(Class<T> type, String name, Object... args) throws BeanException {
return CollectionUtil.addAll(() -> new LinkedList<>(),
null == parent ? null : parent.getBeanListByName(type, name, args),
doGetBeanListByName(type, name, args)
);
}
@Override
public boolean hasBean(Class<?> type, String name) {
boolean res = (null != parent) ? parent.hasBean(type, name) : false;
@@ -188,7 +209,17 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
} else if (beanList.size() > 1) {
throw new BeanException(String.format("Bean[name:%s] 存在多个实例!", name));
}
return getOrNew(beanList.get(0));
return getOrNew(beanList.get(0), args);
}
private <T> T doGetBeanByName(Class<T> type, String name, Object... args) throws BeanException {
List<BeanWrapper> beanList = findBeanList(type, 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), args);
}
private <T> T doGetBean(Class<T> type, Object... args) throws BeanException {
@@ -198,15 +229,15 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
} else if (beanList.size() > 1) {
throw new BeanException(String.format("Bean[type:%s] 存在多个实例!", type));
}
return getOrNew(beanList.get(0));
return getOrNew(beanList.get(0), args);
}
private <T> T doGetBeanByNameAndType(String name, Class<T> type, Object... args) throws BeanException {
private <T> T doGetBeanByTypeAndName(Class<T> type, String name, Object... args) throws BeanException {
BeanWrapper bean = findBean(type, name);
if (null == bean) {
return null;
}
return getOrNew(bean);
return getOrNew(bean, args);
}
private <T> List<T> doGetBeanList(Class<T> type, Object... args) throws BeanException {
@@ -214,7 +245,15 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
if (CollectionUtil.isEmpty(beanList)) {
return null;
}
return getOrNew(beanList);
return getOrNew(beanList, args);
}
private <T> List<T> doGetBeanListByName(Class<T> type, String name, Object... args) throws BeanException {
List<BeanWrapper> beanList = findBeanList(type, name);
if (CollectionUtil.isEmpty(beanList)) {
return null;
}
return getOrNew(beanList, args);
}
private boolean doHasBean(Class<?> type, String name) {
@@ -265,6 +304,22 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
return beanList;
}
/**
* 查找bean
* @param type
* @return
*/
private List<BeanWrapper> findBeanList(Class<?> type, String name) {
Assert.notNull(type, "bean的类型不能为空!");
List<BeanWrapper> beanList = new LinkedList<>();
for (BeanIdentity identity : beanCache.keySet()) {
if (type.isAssignableFrom(identity.getType()) && identity.getName().equals(name)) {
beanList.add(beanCache.get(identity));
}
}
return beanList;
}
/**
* 查找bean
* @param type
@@ -281,8 +336,36 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* 新增一个bean
* @param bean
*/
protected void addBean(BeanWrapper bean) {
protected void addBean(BeanWrapper bean) throws BeanException {
beanCache.put(new BeanIdentity(bean.getName(), bean.getType()), bean);
if (FactoryBean.class.isAssignableFrom(bean.getType())) {
// 工厂bean
if (factoryBeanCache.containsKey(bean.getBeanIdentity())) {
throw new BeanException(String.format("Bean[type:%s name:%s] 存在多个factoryBean!", bean.getType().getName(), bean.getName()));
}
factoryBeanCache.put(bean.getBeanIdentity(), bean);
}
}
/**
* 获取bean的工厂
* @param bean
* @return
*/
protected FactoryBean getFactory(BeanWrapper bean) throws BeanException {
BeanWrapper factoryBeanWrapper = factoryBeanCache.get(bean.getIdentity());
if (null == factoryBeanWrapper) {
return null;
}
dependencyCheck(factoryBeanWrapper);
newInstance(factoryBeanWrapper);
inject(factoryBeanWrapper);
factoryBeanWrapper.init();
if (BeanStatus.INIT == factoryBeanWrapper.getStatus() || BeanStatus.RUNNING == factoryBeanWrapper.getStatus()) {
return (FactoryBean)factoryBeanWrapper.getInstance();
}
throw new BeanException(String.format("Bean[type:%s name%s] 获取工厂 Beanfactory[type:%s name:%s]异常!", bean.getType().getName(), bean.getName(), factoryBeanWrapper.getType().getName(), factoryBeanWrapper.getName()));
}
@Override
@@ -318,19 +401,22 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* @return
* @throws BeanException
*/
protected <T> List<T> getOrNew(List<BeanWrapper> beanList) throws BeanException {
List<T> list = new LinkedList<>();
protected <T> List<T> getOrNew(List<BeanWrapper> beanList, Object... args) throws BeanException {
if (CollectionUtil.isEmpty(beanList)) {
return list;
return null;
}
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()));
dependencyCheck(beanList);
newInstance(beanList, args);
inject(beanList);
beanList.forEach(beanWrapper -> beanWrapper.init());
for (BeanWrapper beanWrapper : beanList) {
if (beanWrapper.getStatus().getStatus() < BeanStatus.INIT.getStatus()) {
throw new BeanException(String.format("Bean[type:%s name:%s]实例化失败!", beanWrapper.getType().getName(), beanWrapper.getName()));
}
list.add(instance);
}
return list;
return beanList.stream().filter(beanWrapper -> BeanStatus.DESTROY != beanWrapper.getStatus()).map(beanWrapper -> (T)beanWrapper.getInstance()).collect(Collectors.toList());
}
/**
@@ -370,7 +456,7 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* @param <T>
* @return
*/
protected <T> T getOrNew(BeanWrapper bean) throws BeanException {
protected <T> T getOrNew(BeanWrapper bean, Object... args) throws BeanException {
try {
return (T)LockUtil.doubleCheckProcess(
() -> !(BeanStatus.INIT == bean.getStatus() || BeanStatus.RUNNING == bean.getStatus()),
@@ -396,13 +482,49 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
}
}
/**
* 依赖关系检测
* @param beanList
* @return
* @throws BeanException
*/
protected void dependencyCheck(List<BeanWrapper> beanList) throws BeanException {
for (BeanWrapper beanWrapper : beanList) {
dependencyCheck(beanWrapper);
}
}
/**
* 实例化
* @param beanList
* @return
* @throws BeanException
*/
protected void newInstance(List<BeanWrapper> beanList, Object... args) throws BeanException {
for (BeanWrapper beanWrapper : beanList) {
newInstance(beanWrapper, args);
}
}
/**
* 注入
* @param beanList
* @return
* @throws BeanException
*/
protected void inject(List<BeanWrapper> beanList) throws BeanException {
for (BeanWrapper beanWrapper : beanList) {
inject(beanWrapper);
}
}
/**
* 依赖关系检测
* @param bean
* @return
* @throws BeanException
*/
protected abstract void dependencyCheck(BeanWrapper bean) throws Exception;
protected abstract void dependencyCheck(BeanWrapper bean) throws BeanException;
/**
* 实例化
@@ -411,7 +533,7 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* @return
* @throws BeanException
*/
protected abstract <T> T newInstance(BeanWrapper bean) throws BeanException;
protected abstract <T> T newInstance(BeanWrapper bean, Object... args) throws BeanException;
/**
* 注入
@@ -419,5 +541,5 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry,
* @return
* @throws BeanException
*/
protected abstract void inject(BeanWrapper bean) throws Exception;
protected abstract void inject(BeanWrapper bean) throws BeanException;
}
@@ -41,6 +41,16 @@ public interface BeanFactory {
*/
<T> T getBean(String name, Object... args) throws BeanException;
/**
* 尝试根据名称获取bean,此处的type不做强制限定,可以是bean的接口或超类型
* @param type
* @param name
* @param args
* @param <T>
* @return
*/
<T> T getBeanByName(Class<T> type, String name, Object... args);
/**
* 尝试根据类型获取bean
* @param type
@@ -81,4 +91,15 @@ public interface BeanFactory {
* @throws BeanException
*/
<T> List<T> getBeanList(Class<T> type, Object... args) throws BeanException;
/**
* 尝试根据名称获取bean,此处的type不做强制限定,可以是bean的接口或超类型
* @param type
* @param name
* @param args
* @param <T>
* @return
* @throws BeanException
*/
<T> List<T> getBeanListByName(Class<T> type, String name, Object... args) throws BeanException;
}
@@ -50,7 +50,7 @@ public class BeanIdentity implements Identity {
Assert.notNull(type, "类型不能为空!");
this.name = name;
this.type = type;
this.identityHashCode = System.identityHashCode(name) + System.identityHashCode(type);
this.identityHashCode = System.identityHashCode(type);
}
/**
@@ -79,6 +79,9 @@ public class BeanIdentity implements Identity {
if (null == obj) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof BeanIdentity)) {
return false;
}
@@ -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;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Bean实例化的方式
* @author: aoshiguchen
* @date: 2022/7/4
*/
@Getter
@AllArgsConstructor
public enum BeanInstantiationMode {
// newInstance
DIRECT(1, "直接"),
METHOD(2, "方法"),
FACTORY(3, "工厂");
private Integer mode;
private String desc;
}
@@ -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;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* bean的匹配模式
* @author: aoshiguchen
* @date: 2022/7/4
*/
@Getter
@AllArgsConstructor
public enum BeanMatchMode {
ByType(1, "根据类型匹配"),
ByName(2, "根据名称匹配"),
ByTypeName(3, "根据类型+名称匹配");
private Integer mode;
private String desc;
}
@@ -56,6 +56,7 @@ public class BeanWrapper implements LifeCycle {
private volatile boolean isInit;
private BeanStatus status;
private boolean isLazy;
private BeanIdentity beanIdentity;
public boolean hasInstance() {
return null != instance;
@@ -63,12 +64,11 @@ public class BeanWrapper implements LifeCycle {
@Override
public void init() {
if (isInit) {
return;
}
if (!hasInstance()) {
if (BeanStatus.INJECT != status) {
return;
}
this.setStatus(BeanStatus.INIT);
log.info("Bean[type:{} name:{}]初始化...", getType().getName(), getName());
isInit = true;
Set<Method> methods = ReflectUtil.getMethods(type);
@@ -239,4 +239,13 @@ public class BeanWrapper implements LifeCycle {
public void run() {
}
public BeanIdentity getIdentity() {
return LockUtil.doubleCheckProcessForNoException(
() -> null == beanIdentity,
this,
() -> beanIdentity = new BeanIdentity(this.name, this.type),
() -> beanIdentity
);
}
}
@@ -0,0 +1,44 @@
/**
* 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/4
*/
public interface FactoryBean<T> {
/**
* 获取bean实例
* @return
* @throws BeanException
*/
T getInstance() throws BeanException;
/**
* 获取Bean身份
* @return
*/
BeanIdentity getBeanIdentity();
}
@@ -21,15 +21,16 @@
*/
package fun.asgc.neutrino.core.bean;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Lazy;
import fun.asgc.neutrino.core.annotation.Order;
import com.google.common.collect.Lists;
import fun.asgc.neutrino.core.annotation.*;
import fun.asgc.neutrino.core.aop.Aop;
import fun.asgc.neutrino.core.exception.BeanException;
import fun.asgc.neutrino.core.runner.ApplicationRunner;
import fun.asgc.neutrino.core.util.*;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -68,54 +69,144 @@ public class SimpleBeanFactory extends AbstractBeanFactory {
beanWrapper.setOrder(order.value());
}
addBean(beanWrapper);
registerBeanForMethod(type);
}
@Override
protected void dependencyCheck(BeanWrapper bean) throws Exception {
LockUtil.doubleCheckProcess(
() -> BeanStatus.REGISTER == bean.getStatus(),
bean,
() -> {
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(bean.getType());
if (CollectionUtil.notEmpty(fieldSet)) {
fieldSet.forEach(field -> {
Autowired autowired = field.getAnnotation(Autowired.class);
if (null == autowired) {
return;
}
String name = field.getName();
// TODO
});
}
/**
* 根据method注册bean
* @param type
*/
private void registerBeanForMethod(Class<?> type) {
Set<Method> methods = ReflectUtil.getMethods(type);
if (CollectionUtil.isEmpty(methods)) {
return;
}
for (Method method : methods) {
Bean bean = method.getAnnotation(Bean.class);
if (null == bean) {
continue;
}
);
String beanName = bean.value();
if (StringUtil.isEmpty(beanName)) {
beanName = method.getName();
}
Class<?> beanType = method.getReturnType();
if (method.getParameters().length > 0) {
throw new BeanException(String.format("Bean[type:%s name:%s] 注册失败,Class:%s method:%s 方法不能带参数!", beanType.getName(), beanName, type.getName(), method.getName()));
}
addBean(beanType, beanName);
}
}
@Override
protected <T> T newInstance(BeanWrapper bean) throws BeanException {
protected void dependencyCheck(BeanWrapper bean) throws BeanException {
try {
LockUtil.doubleCheckProcess(
() -> BeanStatus.REGISTER == bean.getStatus(),
bean,
() -> {
// TODO
bean.setStatus(BeanStatus.DEPENDENCY_CHECKING);
}
);
} catch (Exception e) {
throw new BeanException(String.format("Bean[type:%s name:%s] 依赖检测异常!", bean.getType().getName(), bean.getName()));
}
}
@Override
protected <T> T newInstance(BeanWrapper bean, Object... args) throws BeanException {
try {
return LockUtil.doubleCheckProcess(
() -> BeanStatus.DEPENDENCY_CHECKING == bean.getStatus(),
bean,
() -> {
bean.getClass().newInstance();
// TODO 此处factoryBean可能还未注入、初始化,需要思考优化
FactoryBean factoryBean = getFactory(bean);
if (null != factoryBean) {
bean.setInstance(factoryBean.getInstance());
} else if (ClassUtil.isInterface(bean.getType())) {
bean.setInstance(Aop.get(bean.getType()));
} else if(bean.getType().isAnnotationPresent(Configuration.class)) {
bean.setInstance(ConfigUtil.getYmlConfig(bean.getType()));
} else {
if (ClassUtil.hasNoArgsConstructor(bean.getType())) {
bean.setInstance(Aop.get(bean.getType()));
} else {
// TODO 暂不支持有参构造器
throw new BeanException(String.format("Bean[type:%s name:%s] 没有无参构造器,实例化失败!", bean.getType().getName(), bean.getName()));
}
}
if (null != bean.getInstance()) {
bean.setStatus(BeanStatus.INSTANCE);
}
},
() -> (T)bean.getInstance()
);
} catch (Exception e) {
} catch (BeanException e) {
throw e;
}catch (Exception e) {
throw new BeanException(String.format("Bean[type:%s name:%s] 实例化异常", bean.getType().getName(), bean.getName()), e);
}
}
@Override
protected void inject(BeanWrapper bean) throws Exception {
LockUtil.doubleCheckProcess(
() -> BeanStatus.INSTANCE == bean.getStatus(),
bean,
() -> {
// TODO
}
);
protected void inject(BeanWrapper bean) throws BeanException {
try {
LockUtil.doubleCheckProcess(
() -> BeanStatus.INSTANCE == bean.getStatus(),
bean,
() -> {
Set<Field> fieldSet = ReflectUtil.getInheritChainDeclaredFieldSet(bean.getType());
if (CollectionUtil.isEmpty(fieldSet)) {
bean.setStatus(BeanStatus.INJECT);
return;
}
for (Field field : fieldSet) {
Autowired autowired = field.getAnnotation(Autowired.class);
if (null == autowired) {
continue;
}
String beanName = autowired.value();
if (StringUtil.isEmpty(beanName)) {
beanName = field.getName();
}
Class<?> parameterType = autowired.parameterTypes().length == 0 ? Object.class : autowired.parameterTypes()[0];
BeanMatchMode matchMode = autowired.matchMode();
Object obj = null;
if (matchMode == BeanMatchMode.ByType) {
if (TypeUtil.isListable(field.getType())) {
List list = getBeanList(parameterType);
obj = TypeUtil.listTo(list, field.getType());
} else {
obj = getBean(field.getType());
}
} else if(matchMode == BeanMatchMode.ByName) {
if (TypeUtil.isListable(field.getType())) {
List list = getBeanListByName(parameterType, beanName);
obj = TypeUtil.listTo(list, field.getType());
} else {
obj = getBeanByName(field.getType(), beanName);
}
} else if (matchMode == BeanMatchMode.ByTypeName) {
obj = getBeanByTypeAndName(field.getType(), beanName);
if (TypeUtil.isListable(field.getType())) {
obj = TypeUtil.listTo(Lists.newArrayList(obj), field.getType());
}
}
if (null == obj) {
throw new BeanException(String.format("Bean[type:%s name:%s field:%s] 注入异常", bean.getType().getName(), bean.getName(), field.getName()));
}
ReflectUtil.setFieldValue(field, bean.getInstance(), obj);
}
bean.setStatus(BeanStatus.INJECT);
}
);
} catch (BeanException e){
throw e;
}catch (Exception e) {
throw new BeanException(String.format("Bean[type:%s name:%s] 注入异常", bean.getType().getName(), bean.getName()), e);
}
}
@Override
@@ -147,6 +147,9 @@ public class ApplicationContext implements LifeCycle {
List<ApplicationRunner> applicationRunnerList = this.applicationBeanFactory.getBeanList(ApplicationRunner.class);
if (CollectionUtil.notEmpty(applicationRunnerList)) {
applicationRunnerList.forEach(applicationRunner -> applicationRunner.run(this.environment.getMainArgs()));
}
// for (ApplicationRunner runner : applicationRunnerList) {
// runner.run(this.environment.getMainArgs());
// }
}
}
}
@@ -65,17 +65,17 @@ public class NeutrinoLauncher {
stopWatch.start();
environmentInit();
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();
// this.applicationContainer = new DefaultApplicationContainer(environment);
// SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> {
// context.destroy();
// this.applicationContainer.destroy();
// log.info("Application already stop.");
// });
ApplicationContext context = new ApplicationContext(environment);
context.run();
SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> {
context.destroy();
log.info("Application already stop.");
});
stopWatch.stop();
printLog(environment, stopWatch);
@@ -38,6 +38,7 @@ import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;
/**
*
@@ -239,4 +240,8 @@ public class ClassUtil {
public static boolean isInterface(Class<?> clazz) {
return clazz.isInterface();
}
public static boolean hasNoArgsConstructor(Class<?> clazz) {
return Stream.of(clazz.getConstructors()).filter(c -> c.getParameterCount() == 0).count() > 0;
}
}
@@ -50,6 +50,20 @@ public class LockUtil {
}
}
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
*/
public static void doubleCheckProcessForNoException(BooleanSupplier isLock, Object lock, CodeBlock lockProcess) {
try {
doubleCheckProcess(isLock, lock, lockProcess);
} catch (Exception e) {
// ignore
}
}
/**
* 双重校验处理
* @param isLock
@@ -61,4 +75,16 @@ public class LockUtil {
doubleCheckProcess(isLock, lock, lockProcess);
return nonLockProcess.get();
}
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
* @param nonLockProcess
*/
public static <T> T doubleCheckProcessForNoException(BooleanSupplier isLock, Object lock, CodeBlock lockProcess, Supplier<T> nonLockProcess) {
doubleCheckProcessForNoException(isLock, lock, lockProcess);
return nonLockProcess.get();
}
}
@@ -28,6 +28,7 @@ import fun.asgc.neutrino.core.type.TypeMatchers;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
/**
*
@@ -491,6 +492,57 @@ public class TypeUtil {
return defaultValueMap.get(clazz);
}
/**
* 是否是集合类型
* @param clazz
* @return
*/
public static boolean isCollection(Class<?> clazz) {
return Collection.class.isAssignableFrom(clazz);
}
/**
* 是否可列举
* @param clazz
* @return
*/
public static boolean isListable(Class<?> clazz) {
return clazz.isArray() || isCollection(clazz);
}
/**
* 是否是list
* @param clazz
* @return
*/
public static boolean isList(Class<?> clazz) {
return List.class.isAssignableFrom(clazz);
}
/**
* list转成其他形式
* @param list
* @param targetType
* @return
*/
public static Object listTo(List list, Class<?> targetType) {
if (null == list) {
return null;
}
if (isList(targetType)) {
return list;
}
// 数组
if (targetType.isArray()) {
return list.toArray();
}
// set
if (Set.class.isAssignableFrom(targetType)) {
return list.stream().collect(Collectors.toSet());
}
return null;
}
/**
* 获取继承层级
* 此处假定继承层级最多为100层,避免计算太过耗时
@@ -31,31 +31,31 @@ import org.junit.Test;
public class Test1 {
@Test
public void dogCall() {
public void dogCall() throws Exception {
Dog dog = Aop.get(Dog.class);
dog.call();
}
@Test
public void dogSay() {
public void dogSay() throws Exception {
Dog dog = Aop.get(Dog.class);
System.out.println(dog.say("hello"));
}
@Test
public void catClimb() {
public void catClimb() throws Exception {
Cat cat = Aop.get(Cat.class);
cat.climb();
}
@Test
public void catCalc() {
public void catCalc() throws Exception {
Cat cat = Aop.get(Cat.class);
System.out.println(cat.calc(10, 6));
}
@Test
public void dogCalc() {
public void dogCalc() throws Exception {
Dog dog = Aop.get(Dog.class);
System.out.println(dog.calc(1, 2));
}
@@ -78,38 +78,38 @@ public class Test2 {
}
@Test
public void eat() {
public void eat() throws Exception {
Panda panda = Aop.get(Panda.class);
panda.eat();
}
@Test
public void play() {
public void play() throws Exception {
Panda panda = Aop.get(Panda.class);
panda.play("滑板");
}
@Test
public void division() {
public void division() throws Exception {
Panda panda = Aop.get(Panda.class);
System.out.println(panda.division(10, 5));
panda.division(10, 0);
}
@Test
public void say() {
public void say() throws Exception {
Panda panda = Aop.get(Panda.class);
panda.say("hello");
}
@Test
public void request() {
public void request() throws Exception {
Panda panda = Aop.get(Panda.class);
panda.request("xxx", "yyy");
}
@Test
public void up() {
public void up() throws Exception {
Panda panda = Aop.get(Panda.class);
try {
panda.up();
@@ -21,10 +21,10 @@
*/
package fun.asgc.neutrino.core.aop;
import fun.asgc.neutrino.core.aop.proxy.Proxy;
import fun.asgc.neutrino.core.util.ReflectUtil;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
@@ -35,7 +35,7 @@ import java.lang.reflect.Method;
public class Test3 {
@Test
public void test1() {
public void test1() throws Exception {
Animal animal = Aop.get(Animal.class);
// Animal animal = Proxy.getProxyFactory(ProxyStrategy.ASGC_PROXY).get(Animal.class);
System.out.println(animal);
@@ -43,7 +43,7 @@ public class Test3 {
}
@Test
public void test2() {
public void test2() throws Exception {
Mammal mammal = Aop.get(Mammal.class);
mammal.crawl();
@@ -55,4 +55,33 @@ public class Test3 {
Bear bear = Aop.get(Bear.class);
bear.up();
}
@Test
public void test4() throws InvocationTargetException, IllegalAccessException {
Method hello1 = ReflectUtil.getMethods(A.class).stream().filter(m -> m.getName().equals("hello1")).findFirst().get();
Method hello11 = ReflectUtil.getMethods(B.class).stream().filter(m -> m.getName().equals("hello1")).findFirst().get();
A a = new A();
B b = new B();
// hello1.invoke(a);
// hello1.invoke(b);
hello11.invoke(a); // 异常
hello11.invoke(b);
}
public static class A {
public void hello1() {
System.out.println("hello1");
}
public void hello2() {
System.out.println("hello2");
}
}
public static class B extends A {
@Override
public void hello1() {
super.hello1();
System.out.println("----");
}
}
}
@@ -22,10 +22,12 @@
package fun.asgc.neutrino.core.bean;
import fun.asgc.neutrino.core.aop.Animal;
import fun.asgc.neutrino.core.bean.test1.Cat;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
@@ -48,4 +50,12 @@ public class BeanIdentityTest {
System.out.println(map);
}
@Test
public void test3() {
Cat cat = new Cat();
Map<BeanIdentity, Integer> a = new ConcurrentHashMap<>();
a.put(new BeanIdentity("cat", Cat.class), 1);
System.out.println(a.get(new BeanIdentity("cat", Cat.class)));
}
}
@@ -0,0 +1,35 @@
/**
* 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.test1;
/**
*
* @author: aoshiguchen
* @date: 2022/7/4
*/
public class Animal {
public void call() {
System.out.println("未知动物的叫声");
}
}
@@ -0,0 +1,44 @@
/**
* 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.test1;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Init;
/**
*
* @author: aoshiguchen
* @date: 2022/7/4
*/
@Component
public class Cat extends Animal {
@Init
public void a() {
System.out.println("11111");
}
@Override
public void call() {
System.out.println("喵喵喵");
}
}
@@ -0,0 +1,37 @@
/**
* 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.test1;
import fun.asgc.neutrino.core.annotation.Component;
/**
*
* @author: aoshiguchen
* @date: 2022/7/4
*/
@Component
public class Dog extends Animal {
@Override
public void call() {
System.out.println("汪汪汪");
}
}
@@ -0,0 +1,81 @@
/**
* 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.test1;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Destroy;
import fun.asgc.neutrino.core.annotation.Init;
import fun.asgc.neutrino.core.annotation.NeutrinoApplication;
import fun.asgc.neutrino.core.bean.BeanMatchMode;
import fun.asgc.neutrino.core.bean.BeanStatus;
import fun.asgc.neutrino.core.launcher.NeutrinoLauncher;
import java.util.List;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/7/4
*/
@NeutrinoApplication
public class Launcher {
@Autowired
private Cat cat;
@Autowired(matchMode = BeanMatchMode.ByName, value = "cat")
private Animal cat2;
@Autowired(matchMode = BeanMatchMode.ByType)
private Cat cat3;
@Autowired(matchMode = BeanMatchMode.ByType, parameterTypes = Cat.class)
private List<Cat> cats1;
@Autowired(value = "cat", matchMode = BeanMatchMode.ByName, parameterTypes = Cat.class)
private List<Cat> cats2;
@Autowired
private Dog dog;
@Autowired("dog")
private Dog dog2;
@Autowired(value = "dog", matchMode = BeanMatchMode.ByName, parameterTypes = Dog.class)
private Object[] dogs1;
@Autowired(matchMode = BeanMatchMode.ByType, parameterTypes = Dog.class)
private Set<Dog> dogs2;
@Autowired(matchMode = BeanMatchMode.ByType, parameterTypes = Animal.class)
private List<Animal> list;
@Init
public void init() {
System.out.println("初始化---");
cat.call();
dog.call();
}
@Destroy
public void destroy() {
System.out.println("销毁---");
}
public static void main(String[] args) {
NeutrinoLauncher.run(Launcher.class, args).sync();
}
}
@@ -38,6 +38,10 @@ public class Test1 implements ApplicationRunner {
@Autowired
private TestGlobalExceptionHandler testGlobalExceptionHandler;
public Test1() {
System.out.println("aaa");
}
@Init
public void init() {
log.info("初始化,注册全局异常拦截器{}...", testGlobalExceptionHandler.hashCode());
@@ -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.util;
import org.junit.Test;
/**
*
* @author: aoshiguchen
* @date: 2022/7/4
*/
public class ClassUtilTest {
@Test
public void hasNoArgsConstructor() {
System.out.println(ClassUtil.hasNoArgsConstructor(ClassUtilTest.class));
}
}