package org.test4j.module.spring.strategy; import static org.test4j.tools.commons.AnnotationHelper.getFieldsAnnotatedWith; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Set; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.test4j.module.core.TestContext; import org.test4j.module.core.utility.MessageHelper; import org.test4j.module.spring.annotations.SpringBeanFrom; import org.test4j.module.spring.exception.FindBeanImplClassException; import org.test4j.tools.commons.FieldHelper; import org.test4j.tools.commons.StringHelper; import org.test4j.tools.reflector.imposteriser.Test4JProxy; @SuppressWarnings({ "unchecked", "rawtypes" }) public class SpringBeanFromFactory implements FactoryBean {// , BeanFactoryAware public String fieldName; private Class type = null; public SpringBeanFromFactory() { } public void setFieldName(String fieldName) { this.fieldName = fieldName; } @Override public Object getObject() throws Exception { Class testClazz = TestContext.currTestedClazz(); Object o = Test4JProxy.proxy(testClazz, fieldName); return o; } @Override public Class getObjectType() { if (type == null) {// && beanFactory != null Class testClazz = TestContext.currTestedClazz(); Field field = FieldHelper.getField(testClazz, this.fieldName); this.type = field.getType(); } return type; } @Override public boolean isSingleton() { return true; } /** * 注册tested object下所有的@SpringBeanFrom对象<br> * * @param testedObject */ public static void registerSpringBeanFromField(final DefaultListableBeanFactory beanFactory, Class testedClazz) { Set<Field> beanFields = getFieldsAnnotatedWith(testedClazz, SpringBeanFrom.class); for (Field beanField : beanFields) { SpringBeanFrom beanFor = beanField.getAnnotation(SpringBeanFrom.class); String fieldName = beanField.getName(); String beanName = beanFor.value(); if (StringHelper.isBlankOrNull(beanName)) { beanName = fieldName; } registerProxyBeanDefinition(beanFactory, beanName, fieldName); } } /** * 定义SpringBeanFor的代理proxy bean * * @param beanFactory * @param beanName * @param byName * @throws FindBeanImplClassException */ private static void registerProxyBeanDefinition(final DefaultListableBeanFactory beanFactory, final String beanName, final String fieldName) { // SpringBeanFrom采用的是覆盖原有的bean定义 if (beanFactory.containsBeanDefinition(beanName)) { MessageHelper .info(String .format("SpringBeanFrom BeanName[%s] has been defined in application context, so override bean definition.", beanName)); } RootBeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClassName(SpringBeanFromFactory.class.getName()); beanDefinition.setScope("singleton"); beanDefinition.setAutowireCandidate(true); beanDefinition.setLazyInit(false); beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME); MutablePropertyValues properties = new MutablePropertyValues(new HashMap<String, String>() { private static final long serialVersionUID = 1L; { this.put("fieldName", fieldName); } }); beanDefinition.setPropertyValues(properties); beanFactory.registerBeanDefinition(beanName, beanDefinition); } }