org.tinygroup.tinyioc.impl.BeanContainerImpl Maven / Gradle / Ivy
/**
* Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
*
* Licensed under the GPL, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.tinygroup.tinyioc.impl;
import org.apache.commons.beanutils.BeanUtils;
import org.tinygroup.tinyioc.*;
import org.tinygroup.tinyioc.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
/**
* Created by luoguo on 13-12-27.
*/
public class BeanContainerImpl implements BeanContainer {
private DynamicProxy proxy = new DynamicProxy();
private ThreadLocal threadLocal = new ThreadLocal();
private Map nameMap = new HashMap();
private Map scopeMap = new HashMap();
private List classList = new ArrayList();
private Map objectMap = new HashMap();
private Map typeConverterMap = new HashMap();
private BeanContainer parent = null;
private List beanContainerList = new ArrayList();
private ClassLoader classLoader;
public BeanContainerImpl() {
}
public BeanContainerImpl(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public void registerClass(Class clazz) {
Named named = clazz.getAnnotation(Named.class);
if (named != null && named.value().length() > 0) {
nameMap.put(named.value(), clazz);
}
String scope = "singleton";
Request request = clazz.getAnnotation(Request.class);
if (request != null) {
scope = "request";
}
Prototype prototype = clazz.getAnnotation(Prototype.class);
if (prototype != null) {
scope = "prototype";
}
classList.add(clazz);
scopeMap.put(clazz, scope);
}
public T getBeanByName(String name) {
Class clazz = nameMap.get(name);
if (clazz == null) {
throw new RuntimeException(String.format("bean with name [%s] not found", name));
}
try {
return (T) getBeanByType(clazz);
} catch (RuntimeException e) {
if (parent != null) {
return (T) parent.getBeanByName(name);
} else {
throw e;
}
}
}
public T getBeanByType(String type) {
Class clazz = null;
try {
clazz = Class.forName(type);
return (T) getBeanByType(clazz);
} catch (ClassNotFoundException e) {
if (parent != null) {
return (T) parent.getBeanByType(type);
}
throw new RuntimeException(e);
}
}
public T getBeanByType(Class clazz) {
String scope = scopeMap.get(clazz);
T object = null;
if (scope != null) {
if (("singleton").equalsIgnoreCase(scope)) {
object = getSingletonObject(clazz);
} else if (("prototype").equalsIgnoreCase(scope)) {
object = getPrototypeObject(clazz);
} else if (("request").equalsIgnoreCase(scope)) {
object = getThreadObject(clazz);
}
} else {
//如果是子孙类或实现了接口
for (Class clz : classList) {
if (isSubClass(clz, clazz)) {
object = (T) getBeanByType(clz);
}
}
}
if (object != null) {
return object;
}
if (parent != null) {
return parent.getBeanByType(clazz);
}
throw new RuntimeException(clazz.getName() + " not found in container.");
}
private void buildObject(T object, Class clazz) {
for (Field field : clazz.getDeclaredFields()) {
Inject inject = field.getAnnotation(Inject.class);
//如果属性上有注解
if (inject != null) {
// String name = null;
Named named = field.getAnnotation(Named.class);
Value valueAnnotation = field.getAnnotation(Value.class);
if (named != null && named.value().length() > 0) {
// name = named.value();
}
Object value = null;
Type fc = field.getGenericType();
if (fc instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) fc;
Class genericClazz = (Class) pt.getActualTypeArguments()[0];
value = getCollectionObject(field, genericClazz);
} else if (valueAnnotation != null && valueAnnotation.value().length() > 0) {
//如果是设置的固定值
value = getValueObject(field, valueAnnotation.value());
} else {
value = getSingleObject(field, inject, named);
}
if (value != null) {
try {
BeanUtils.setProperty(object, field.getName(), value);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException(String.format("类%s的属性%s对应的Bean找不到!", object.getClass().getName(), field.getName()));
}
}
}
}
private Object getSingleObject(Field field, Inject inject, Named named) {
Object value;
if (named != null && named.value().length() > 0) {
//如果是按名字
value = getBeanByName(named.value());
} else {
//自动进行检测
value = getBeanByType(field.getType());
if (value == null) {
value = getBeanByName(field.getName());
}
}
return value;
}
private Object getValueObject(Field field, String stringValue) {
Object value;
TypeConverter converter = typeConverterMap.get(field.getType());
if (converter != null) {
value = converter.convert(stringValue);
} else {
value = stringValue;
}
return value;
}
private Object getCollectionObject(Field field, Class clazz) {
Object value = null;
if (field.getType().equals(List.class)) {
value = getBeanList(clazz);
} else if (field.getType().equals(Set.class)) {
value = getBeanSet(clazz);
} else if (field.getType().equals(Collection.class)) {
value = getBeanCollection(clazz);
}
return value;
}
public static boolean isSubClass(Class a, Class b) {
Type genericSuperclass = a.getGenericSuperclass();
for (Type type : a.getGenericInterfaces()) {
if (type.equals(b)) {
return true;
}
boolean is = isSubClass((Class) type, b);
if (is) {
return true;
}
}
if (genericSuperclass != null) {
if (genericSuperclass.equals(b)) {
return true;
} else {
boolean is = isSubClass((Class) genericSuperclass, b);
if (is) {
return true;
}
}
}
return false;
}
private T getThreadObject(Class clazz) {
Map threadMap = (Map) threadLocal.get();
if (threadMap == null) {
threadMap = new HashMap();
threadLocal.set(threadMap);
}
T object = (T) threadMap.get(clazz);
if (object == null) {
object = getPrototypeObject(clazz);
threadMap.put(clazz, object);
}
return object;
}
private T getPrototypeObject(Class clazz) {
try {
T object = null;
if (!isInterceptorClass(clazz) && proxy.isMatchClassName(clazz.getName())) {
object = proxy.getProxyObject(clazz);
} else {
object = clazz.newInstance();
}
buildObject(object, clazz);
return object;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
boolean isInterceptorClass(Class clz) {
if (isSubClass(clz, InterceptorAfter.class)) {
return true;
}
if (isSubClass(clz, InterceptorBefore.class)) {
return true;
}
return isSubClass(clz, InterceptorException.class);
}
private T getSingletonObject(Class clazz) {
T object = (T) objectMap.get(clazz);
if (object == null) {
object = getPrototypeObject(clazz);
objectMap.put(clazz, object);
}
return object;
}
public List getBeanList(String type) {
Class typeClazz = null;
try {
typeClazz = Class.forName(type);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return getBeanList(typeClazz);
}
public List getBeanList(Class clazz) {
List list = new ArrayList();
for (Class> clz : classList) {
if (isSubClass(clz, clazz)) {
T beanByType = (T) getBeanByType(clz);
list.add(beanByType);
}
}
return list;
}
public Set getBeanSet(String type) {
Class typeClazz = null;
try {
typeClazz = Class.forName(type);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return getBeanSet(typeClazz);
}
public Set getBeanSet(Class clazz) {
Set set = new HashSet();
for (Class> clz : classList) {
if (isSubClass(clz, clazz)) {
T beanByType = (T) getBeanByType(clz);
set.add(beanByType);
}
}
return set;
}
public Collection getBeanCollection(String type) {
return getBeanList(type);
}
public Collection getBeanCollection(Class clazz) {
return getBeanList(clazz);
}
public boolean isExistBeanByName(String name) {
return nameMap.containsKey(name);
}
public boolean isExistBeanByType(String type) {
try {
return isExistBeanByType(Class.forName(type));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public boolean isExistBeanByType(Class clazz) {
return typeConverterMap.containsKey(clazz);
}
public void addTypeConverter(TypeConverter typeConverter) {
typeConverterMap.put(typeConverter.getType(), typeConverter);
}
public void addAop(AopDefine aopDefine) {
proxy.addAop(aopDefine);
}
public void setParent(BeanContainer beanContainer) {
this.parent = beanContainer;
}
public void addBeanContainer(BeanContainer beanContainer) {
if (!beanContainerList.contains(beanContainer)) {
beanContainerList.add(beanContainer);
beanContainer.setParent(this);
}
}
public void removeBeanContainer(BeanContainer beanContainer) {
if (beanContainerList.contains(beanContainer)) {
beanContainerList.remove(beanContainer);
beanContainer.setParent(null);
}
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public ClassLoader getClassLoader() {
if (classLoader == null) {
return this.getClass().getClassLoader();
}
return classLoader;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy