针对接口bean的优化,若接口有且仅有唯一实现类,则采用该实现类作为实现.

This commit is contained in:
aoshiguchen
2022-07-07 16:20:15 +08:00
parent d9f68be1f2
commit 025903561d
6 changed files with 194 additions and 7 deletions
@@ -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;
@@ -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<Class<?>> 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;
}
}
@@ -34,7 +34,6 @@ import java.util.Set;
* @author: aoshiguchen
* @date: 2022/7/4
*/
@NonIntercept(false)
@NeutrinoApplication
public class Launcher {
@@ -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();
}
@@ -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("收音机播放");
}
}
@@ -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();
}
}