package org.theonefx.wcframework.ioc;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.theonefx.wcframework.core.BeanFactoryAware;
import org.theonefx.wcframework.core.BeanNameAware;
import org.theonefx.wcframework.core.ClassWrapper;
import org.theonefx.wcframework.core.InitializableBean;
import org.theonefx.wcframework.core.TypeConverter;
import org.theonefx.wcframework.core.exception.BeanCreationException;
import org.theonefx.wcframework.core.exception.BeansException;
import org.theonefx.wcframework.ioc.exception.BeanInitializationException;
import org.theonefx.wcframework.ioc.exception.BeanNotOfRequiredTypeException;
import org.theonefx.wcframework.ioc.val.MutablePropertyValues;
import org.theonefx.wcframework.ioc.val.TypedStringValue;
import org.theonefx.wcframework.utils.Assert;
import org.theonefx.wcframework.utils.ClassUtils;
import org.theonefx.wcframework.utils.ObjectUtils;
import org.theonefx.wcframework.utils.PropertyAccessorUtils;
import org.theonefx.wcframework.utils.ReflectionUtils;
/**
* @file : BeanFactorySupport.java
* @package : org.theonefx.wcframework.ioc.factory
* @class : BeanFactorySupport
* @author : TheoneFx
* @time : 2011-8-17
* @version : 1.0
* @Description : bean工厂支持类,负责bean创建和获取流程的管理
*/
abstract class AbstractBeanFactory extends BeanFactoryPostProcesser implements BeanFactory {
private final Map<String, Scope> scopes = new HashMap<String, Scope>();
private final ThreadLocal<Map<String, Object>> creatingBeans = new ThreadLocal<Map<String, Object>>();
private final InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();
private final ConstructorResolver constructorResolver = new ConstructorResolver(this);
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String id, final Class<T> requiredType) throws BeansException {
Object bean = null;
// 先从单例缓存中查找对象
Object sharedInstance = getSingleton(id);
if (sharedInstance != null) {
if (log.isDebugEnabled()) {
log.debug("获得缓存的单例Bean实例[" + id + "]");
}
bean = getObjectFromFactoryBean(sharedInstance, id, null);
} else if (creatingBeans.get() != null && creatingBeans.get().containsKey(id)) {
bean = creatingBeans.get().get(id);
} else {
markBeanDefinitionCreated(id);
final RootBeanDefinition mbd = getMergedBeanDefinition(id);
if (mbd.isSingleton()) {
// 单例Bean
sharedInstance = getSingleton(id, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return createBean(id, mbd);
}
});
bean = getObjectFromFactoryBean(sharedInstance, id, mbd);
} else if (mbd.isPrototype()) {
// 原型Bean
Object prototypeInstance = createBean(id, mbd);
bean = getObjectFromFactoryBean(prototypeInstance, id, mbd);
} else {
// 其他Scope的Bean
String scopeName = mbd.getScope();
final Scope scope = getRegisteredScope(scopeName);
if (scope == null) {
throw new IllegalStateException("没有找到名称为[" + scopeName + "]的生命周期对象");
}
Object scopedInstance = scope.get(id, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return createBean(id, mbd);
}
});
bean = getObjectFromFactoryBean(scopedInstance, id, mbd);
}
}
// 检查最终Object的类型
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(id, requiredType, bean.getClass());
}
return (T) bean;
}
protected Object createBean(String id, RootBeanDefinition mbd) {
if (log.isDebugEnabled()) {
log.debug("开始创建Bean实例 [" + id + "]");
}
Class<?> clazz = resolveBeanClass(mbd, id);
ClassWrapper<?> classWrapper = ClassWrapper.getWrapper(clazz);
// 先合并处理BeanDefinition
applyMergedBeanDefinitionPostProcessors(mbd, classWrapper, id);
// 创建真正的bean实例,但是有可能是aop封装的哦
Object beanInstance = doCreateBean(id, mbd, classWrapper);
if (log.isDebugEnabled()) {
log.debug("结束创建Bean实例 [" + id + "]");
}
return beanInstance;
}
protected Object doCreateBean(final String id, final RootBeanDefinition mbd, ClassWrapper<?> classWrapper) {
Object orangeObject = null;
try {
// 这里可能返回一个代理对象,而不是直接创建bean实例。如果返回的不是null,那就跳过真实对象的生成了;
orangeObject = resolveBeforeInstantiation(id, classWrapper, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(id, "实例化之前PostProcess失败", ex);
}
if (orangeObject != null) {
if (log.isDebugEnabled()) {
log.debug("实例化之前PostProcess返回一个[" + id + "]的代理Bean[" + orangeObject + "]");
}
}
// 创建真是bean的封装对象
BeanWrapper instanceWrapper = null;
if (orangeObject == null) {
instanceWrapper = createBeanInstanceWrapper(id, mbd, classWrapper);
orangeObject = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
}
ClassWrapper<?> orangrClassWrapper = orangeObject != null ? ClassWrapper.getWrapper(orangeObject.getClass()) : null;
ClassWrapper<?> wrapperToUse = orangrClassWrapper != null ? orangrClassWrapper : classWrapper;
// 这里可能生成AOP代理对象
Object exposedObject = applyBeanPostProcessAfterInstantiation(id, mbd, wrapperToUse, orangeObject);
Map<String, Object> creatings = creatingBeans.get();
if (creatings == null) {
creatings = new HashMap<String, Object>();
creatingBeans.set(creatings);
}
creatings.put(id, exposedObject);
try {
if (instanceWrapper != null) {
// 填充bean的属性
populateBean(id, mbd, instanceWrapper);
}
} catch (Throwable ex) {
ex.printStackTrace();
throw new BeanCreationException(id, "初始化bean实例失败", ex);
} finally {
creatings.remove(id);
}
if (exposedObject != null) {
// 初始化bean实例
exposedObject = initializeBean(id, exposedObject, wrapperToUse, mbd);
}
return exposedObject;
}
/**
* @ClassName : AbstractBeanFactory
* @Author : 陈曦
* @Date : 2013-2-25 下午09:40:39
* @Description : 初始化bean,先调用initMethod,如果没有initmethod则会检查是不是一个InitializableBean,如果是的话就调用InitializableBean的initilize方法
* <p>只有在实例真正创建的时候才会调用,也就是说如果是单例的bean,初始化只会进行一次
*/
protected Object initializeBean(final String beanName, final Object bean, ClassWrapper<?> classWrapper, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(mbd, bean, classWrapper, beanName);
if (wrappedBean == null) {
wrappedBean = bean;
}
if (mbd.hasInitMethod()) {
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "调用初始化方法失败", ex);
}
} else {
if (bean instanceof InitializableBean) {
try {
((InitializableBean) bean).initialize();
} catch (Exception e) {
throw new BeanInitializationException("Bean初始化出错", e);
}
}
if (bean instanceof BeanFactoryAware) {
BeanFactoryAware aware = (BeanFactoryAware) bean;
aware.setBeanFactory(this);
}
}
wrappedBean = applyBeanPostProcessorsAfterInitialization(mbd, bean, classWrapper, beanName);
if (wrappedBean == null) {
wrappedBean = bean;
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
String initMethodName = mbd.getInitMethodName();
final Method initMethod = ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName);
if (initMethod == null) {
if (log.isDebugEnabled()) {
log.debug("在Bean[" + beanName + "]上没有找到指定的初始化方法 [" + initMethodName + "]");
}
return;
}
if (log.isDebugEnabled()) {
log.debug("调用Bean[" + beanName + "]的初始化方法 [" + initMethodName + "]");
}
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
ReflectionUtils.makeAccessible(initMethod);
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
initMethod.invoke(bean);
return null;
}
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
} else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
protected void populateBean(String id, BeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(id, "无法为null对象设置属性");
} else {
return;
}
}
if (hasPropertyPostProcess()) {
pvs = applyPostProcessPropertyValues(pvs, bw.getPropertyDescriptors(), bw.getWrappedInstance(), id);
}
applyPropertyValues(id, mbd, bw, pvs);
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
try {
bw.setPropertyValues(mpvs);
return;
} catch (BeansException ex) {
throw new BeanCreationException(beanName, "设置属性值出错", ex);
}
}
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = bw;
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 处理value
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
} else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
} else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic()
&& !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
} else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
} catch (BeansException ex) {
throw new BeanCreationException(beanName, "设置属性值出错", ex);
}
}
private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
if (converter instanceof BeanWrapperImpl) {
return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
} else {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
return converter.convertIfNecessary(value, pd.getPropertyType());
}
}
protected BeanWrapper createBeanInstanceWrapper(String id, RootBeanDefinition mbd, ClassWrapper<?> classWrapper) {
if (mbd.getFactoryMethodName() != null) {
// 从工厂方法生成
return instantiateUsingFactoryMethod(id, classWrapper, mbd);
} else if (mbd.hasConstructorArgumentValues()) {
// 自动选择构造函数
return autowireInstantiate(id, classWrapper, mbd);
} else {
// 使用无参构造函数
return instantiateUsingNonArgs(id, classWrapper, mbd);
}
}
protected BeanWrapper instantiateUsingNonArgs(final String beanName, final ClassWrapper<?> classWrapper, final RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return getInstantiationStrategy().instantiate(classWrapper, mbd, beanName);
}
}, getAccessControlContext());
} else {
beanInstance = getInstantiationStrategy().instantiate(classWrapper, mbd, beanName);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "实例化Bean失败", ex);
}
}
protected BeanWrapper instantiateUsingFactoryMethod(String beanId, ClassWrapper<?> classWrapper, RootBeanDefinition mbd) {
return constructorResolver.instantiateUsingFactoryMethod(classWrapper, beanId, mbd);
}
protected BeanWrapper autowireInstantiate(String beanId, ClassWrapper<?> classWrapper, RootBeanDefinition mbd) {
return constructorResolver.autowireConstructor(classWrapper, beanId, mbd);
}
private Object getObjectFromFactoryBean(Object beanInstance, String id, RootBeanDefinition mbd) {
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object bean = null;
if (mbd == null) {
bean = getCachedObjectForFactoryBean(id);
}
if (bean == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(id)) {
mbd = getMergedBeanDefinition(id);
}
bean = getObjectFromFactoryBean(factory, id);
}
return bean;
}
public Scope getRegisteredScope(String scopeName) {
Assert.notNull(scopeName, "Scope 名称不能为空");
return this.scopes.get(scopeName);
}
}