From 025903561d21522cf7f5bfd842f9511566d99ee6 Mon Sep 17 00:00:00 2001 From: aoshiguchen <1052045476@qq.com> Date: Thu, 7 Jul 2022 16:20:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=92=88=E5=AF=B9=E6=8E=A5=E5=8F=A3bean?= =?UTF-8?q?=E7=9A=84=E4=BC=98=E5=8C=96=EF=BC=8C=E8=8B=A5=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=9C=89=E4=B8=94=E4=BB=85=E6=9C=89=E5=94=AF=E4=B8=80=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=B1=BB=EF=BC=8C=E5=88=99=E9=87=87=E7=94=A8=E8=AF=A5?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=B1=BB=E4=BD=9C=E4=B8=BA=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../asgc/neutrino/core/bean/BeanWrapper.java | 1 + .../neutrino/core/bean/SimpleBeanFactory.java | 60 +++++++++++++++++-- .../neutrino/core/bean/test1/Launcher.java | 1 - .../asgc/neutrino/core/bean/test1/Player.java | 49 +++++++++++++++ .../neutrino/core/bean/test1/RadioPlayer.java | 45 ++++++++++++++ .../asgc/neutrino/core/bean/test1/Test1.java | 45 ++++++++++++++ 6 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Player.java create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/RadioPlayer.java create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Test1.java diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/BeanWrapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/BeanWrapper.java index bd9dff4b..04fc7276 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/BeanWrapper.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/BeanWrapper.java @@ -55,6 +55,7 @@ public class BeanWrapper implements LifeCycle { private BeanWrapper factoryBean; private BeanInstantiationMode instantiationMode; private Method instantiationMethod; + private boolean isNonIntercept; public boolean hasInstance() { return null != instance; diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/SimpleBeanFactory.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/SimpleBeanFactory.java index 923374ee..3aa2b27f 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/SimpleBeanFactory.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/SimpleBeanFactory.java @@ -33,6 +33,7 @@ import fun.asgc.neutrino.core.runner.ApplicationRunner; import fun.asgc.neutrino.core.util.*; import lombok.extern.slf4j.Slf4j; +import javax.annotation.processing.Filer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashSet; @@ -70,7 +71,8 @@ public class SimpleBeanFactory extends AbstractBeanFactory { .setLazy(Boolean.FALSE) .setOrder(Integer.MAX_VALUE) .setStatus(BeanStatus.REGISTER) - .setInstantiationMode(BeanInstantiationMode.DIRECT); + .setInstantiationMode(BeanInstantiationMode.DIRECT) + .setNonIntercept(false); Lazy lazy = ClassUtil.getAnnotation(type, Lazy.class); if (null != lazy) { beanWrapper.setLazy(lazy.value()); @@ -79,6 +81,21 @@ public class SimpleBeanFactory extends AbstractBeanFactory { if (null != order) { beanWrapper.setOrder(order.value()); } + // ApplicationRunner、Configuration、Interceptor、Filter、ExceptionHandler、ResultAdvice默认不拦截 + if (ApplicationRunner.class.isAssignableFrom(type) || + type.isAnnotationPresent(Configuration.class) || + Interceptor.class.isAssignableFrom(type) || + Filer.class.isAssignableFrom(type) || + ExceptionHandler.class.isAssignableFrom(type) || + ResultAdvice.class.isAssignableFrom(type) + ) { + beanWrapper.setNonIntercept(true); + } + NonIntercept nonIntercept = ClassUtil.getAnnotation(type, NonIntercept.class); + if (null != nonIntercept) { + beanWrapper.setNonIntercept(nonIntercept.value()); + } + addBean(beanWrapper); registerBeanForMethod(beanWrapper, type); return beanWrapper; @@ -111,6 +128,7 @@ public class SimpleBeanFactory extends AbstractBeanFactory { beanWrapper.setFactoryBean(factoryBean); beanWrapper.setInstantiationMode(BeanInstantiationMode.METHOD); beanWrapper.setInstantiationMethod(method); + beanWrapper.setNonIntercept(false); Lazy lazy = method.getAnnotation(Lazy.class); if (null != lazy) { @@ -146,18 +164,30 @@ public class SimpleBeanFactory extends AbstractBeanFactory { () -> BeanStatus.DEPENDENCY_CHECKING == bean.getStatus(), bean, () -> { - NonIntercept nonIntercept = ClassUtil.getAnnotation(bean.getType(), NonIntercept.class); - boolean isNonIntercept = (null != nonIntercept && nonIntercept.value()) ? true : false; - if (BeanInstantiationMode.DIRECT == bean.getInstantiationMode()) { // 直接实例化 if (ClassUtil.isInterface(bean.getType())) { - bean.setInstance(Aop.get(bean.getType())); + Class implementationType = findOneImplementationAndReturn(bean.getType()); + // 如果是一个接口,且有唯一实现类,则采用该实现类的实例作为bean。否则直接代理该接口 + if (null == implementationType) { + bean.setInstance(Aop.get(bean.getType())); + } else { + if (ClassUtil.hasNoArgsConstructor(implementationType)) { + if (bean.isNonIntercept()) { + bean.setInstance(implementationType.newInstance()); + } else { + bean.setInstance(Aop.get(implementationType, bean.getType())); + } + } else { + // TODO 暂不支持有参构造器 + throw new BeanException(String.format("Bean[type:%s name:%s] 没有无参构造器,实例化失败!", bean.getType().getName(), bean.getName())); + } + } } else if(bean.getType().isAnnotationPresent(Configuration.class)) { bean.setInstance(ConfigUtil.getYmlConfig(bean.getType())); } else { if (ClassUtil.hasNoArgsConstructor(bean.getType())) { - if (isNonIntercept) { + if (bean.isNonIntercept()) { bean.setInstance(bean.getType().newInstance()); } else { bean.setInstance(Aop.get(bean.getType())); @@ -288,4 +318,22 @@ public class SimpleBeanFactory extends AbstractBeanFactory { registerBean(clazz, beanName); }); } + + /** + * 查找指定接口的唯一实现类,若存在一个则返回 + * @param clazz + * @return + */ + private Class findOneImplementationAndReturn(Class clazz) { + if (!ClassUtil.isInterface(clazz) || CollectionUtil.isEmpty(this.classes)) { + return null; + } + Set> cls = classes.stream().filter(c -> clazz.isAssignableFrom(c) + && !ClassUtil.isInterface(c) && !ClassUtil.isAbstract(c) && !ClassUtil.isStatic(c) && ClassUtil.isPublic(c) + ).collect(Collectors.toSet()); + if (cls.size() == 1) { + return cls.iterator().next(); + } + return null; + } } diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Launcher.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Launcher.java index 2e1a2dfd..845a4950 100644 --- a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Launcher.java +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Launcher.java @@ -34,7 +34,6 @@ import java.util.Set; * @author: aoshiguchen * @date: 2022/7/4 */ -@NonIntercept(false) @NeutrinoApplication public class Launcher { diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Player.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Player.java new file mode 100644 index 00000000..9ed5e718 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Player.java @@ -0,0 +1,49 @@ +/** + * 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/7 + */ + +@Component +public interface Player { + + /** + * 开机 + */ + void on(); + + /** + * 关机 + */ + void off(); + + /** + * 播放 + */ + void play(); +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/RadioPlayer.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/RadioPlayer.java new file mode 100644 index 00000000..ee48b383 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/RadioPlayer.java @@ -0,0 +1,45 @@ +/** + * 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/7 + */ +public class RadioPlayer implements Player { + + @Override + public void on() { + System.out.println("收音机开机"); + } + + @Override + public void off() { + System.out.println("收音机关机"); + } + + @Override + public void play() { + System.out.println("收音机播放"); + } +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Test1.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Test1.java new file mode 100644 index 00000000..c607a5ac --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test1/Test1.java @@ -0,0 +1,45 @@ +/** + * 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.Component; +import fun.asgc.neutrino.core.runner.ApplicationRunner; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/7 + */ +@Component +public class Test1 implements ApplicationRunner { + + @Autowired + private Player player; + + @Override + public void run(String[] args) { + player.on(); + player.play(); + player.off(); + } +}