bean容器重构,支持按照名字、类型、名字+类型三种方式注入.
This commit is contained in:
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+2
-6
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user