增强IOC容器,支持Spring注解
ioc2-3(1).png
- 定义BeanPostProcessor接口
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
- 定义Autowired注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
- 定义注解处理类
public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
private AutowireCapableBeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Object result = bean;
Class<?> clazz = result.getClass();
Field[] fields = clazz.getDeclaredFields();
if (fields != null) {
for (Field field : fields) {
boolean isAutowired = field.isAnnotationPresent(Autowired.class);
if (isAutowired) {
String filedName = field.getName();
Object autowireObj = this.getBeanFactory().getBean(filedName);
try {
field.setAccessible(true);
field.set(bean, autowireObj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return result;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return null;
}
public AutowireCapableBeanFactory getBeanFactory() {
return beanFactory;
}
public void setBeanFactory(AutowireCapableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
}
- 抽象出AbstractBeanFactory类
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory, BeanDefinitionRegistry {
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
private List<String> beanDefinitionNames = new ArrayList<>();
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
public AbstractBeanFactory() {
}
public void refresh() {
for (String beanName : beanDefinitionNames) {
try {
getBean(beanName);
} catch (BeansException e) {
e.printStackTrace();
}
}
}
public Object getBean(String beanName) throws BeansException {
Object singleton = this.getSingleton(beanName);
if (singleton == null) {
singleton = this.earlySingletonObjects.get(beanName);
if (singleton == null) {
BeanDefinition bd = beanDefinitionMap.get(beanName);
singleton = createBean(bd);
this.registerBean(beanName, singleton);
applyBeanPostProcessorsBeforeInitialization(singleton, beanName);
if (bd.getInitMethodName() != null && !bd.getInitMethodName().equals("")) {
invokeInitMethod(bd, singleton);
}
applyBeanPostProcessorsAfterInitialization(singleton, beanName);
}
}
if (singleton == null) {
throw new BeansException("bean is null.");
}
return singleton;
}
private void invokeInitMethod(BeanDefinition bd, Object obj) {
Class<?> clz = obj.getClass();
Method method = null;
try {
method = clz.getMethod(bd.getInitMethodName());
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
method.invoke(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public Boolean containsBean(String name) {
return containsSingleton(name);
}
public void registerBean(String beanName, Object obj) {
this.registerSingleton(beanName, obj);
}
@Override
public void registerBeanDefinition(String name, BeanDefinition bd) {
this.beanDefinitionMap.put(name,bd);
this.beanDefinitionNames.add(name);
if (!bd.isLazyInit()) {
try {
getBean(name);
} catch (BeansException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void removeBeanDefinition(String name) {
this.beanDefinitionMap.remove(name);
this.beanDefinitionNames.remove(name);
this.removeSingleton(name);
}
@Override
public BeanDefinition getBeanDefinition(String name) {
return this.beanDefinitionMap.get(name);
}
@Override
public boolean containsBeanDefinition(String name) {
return this.beanDefinitionMap.containsKey(name);
}
@Override
public boolean isSingleton(String name) {
return this.beanDefinitionMap.get(name).isSingleton();
}
@Override
public boolean isPrototype(String name) {
return this.beanDefinitionMap.get(name).isPrototype();
}
@Override
public Class<?> getType(String name) {
return this.beanDefinitionMap.get(name).getClass();
}
private Object createBean(BeanDefinition bd) {
Class<?> clz = null;
Object obj = doCreateBean(bd);
this.earlySingletonObjects.put(bd.getId(), obj);
try {
clz = Class.forName(bd.getClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
populateBean(bd, clz, obj);
return obj;
}
private Object doCreateBean(BeanDefinition bd) {
Class<?> clz = null;
Object obj = null;
Constructor<?> con = null;
try {
clz = Class.forName(bd.getClassName());
ConstructorArgumentValues argumentValues = bd.getConstructorArgumentValues();
if (!argumentValues.isEmpty()) {
Class<?>[] paramTypes = new Class<?>[argumentValues.getArgumentCount()];
Object[] paramValues = new Object[argumentValues.getArgumentCount()];
for (int i = 0; i < argumentValues.getArgumentCount(); i++) {
ConstructorArgumentValue argumentValue = argumentValues.getIndexedArgumentValue(i);
if ("String".equals(argumentValue.getType()) || "java.lang.String".equals(argumentValue.getType())) {
paramTypes[i] = String.class;
paramValues[i] = argumentValue.getValue();
} else if ("Integer".equals(argumentValue.getType()) || "java.lang.Integer".equals(argumentValue.getType())) {
paramTypes[i] = Integer.class;
paramValues[i] = Integer.valueOf((String) argumentValue.getValue());
} else if ("int".equals(argumentValue.getType())) {
paramTypes[i] = int.class;
paramValues[i] = Integer.valueOf((String) argumentValue.getValue()).intValue();
} else {
paramTypes[i] = String.class;
paramValues[i] = argumentValue.getValue();
}
}
try {
con = clz.getConstructor(paramTypes);
obj = con.newInstance(paramValues);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else {
obj = clz.newInstance();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return obj;
}
private void populateBean(BeanDefinition bd, Class<?> clz, Object obj) {
handleProperties(bd, clz, obj);
}
private void handleProperties(BeanDefinition bd, Class<?> clz, Object obj) {
PropertyValues propertyValues = bd.getPropertyValues();
if (!propertyValues.isEmpty()) {
for (int i = 0; i < propertyValues.size(); i++) {
PropertyValue propertyValue = propertyValues.getPropertyValueList().get(i);
String pName = propertyValue.getName();
String pType = propertyValue.getType();
Object pValue = propertyValue.getValue();
boolean isRef = propertyValue.getIsRef();
Class<?>[] paramTypes = new Class<?>[1];
Object[] paramValues = new Object[1];
if (!isRef) {
if ("String".equals(pType) || "java.lang.String".equals(pType)) {
paramTypes[0] = String.class;
} else if ("Integer".equals(pType) || "java.lang.Integer".equals(pType)) {
paramTypes[0] = Integer.class;
} else if ("int".equals(pType)) {
paramTypes[0] = int.class;
} else {
paramTypes[0] = String.class;
}
paramValues[0] = pValue;
} else {
try {
paramTypes[0] = Class.forName(pType);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
paramValues[0] = getBean((String)pValue);
} catch (BeansException e) {
e.printStackTrace();
}
}
String methodName = "set" + pName.substring(0, 1).toUpperCase() + pName.substring(1);
Method method = null;
try {
method = clz.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
method.invoke(obj, paramValues);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
abstract public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
abstract public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
}
实现AutowireCapableBeanFactory,为Autowired注入Bean做准备
public class AutowireCapableBeanFactory extends AbstractBeanFactory {
private final List<AutowiredAnnotationBeanPostProcessor> beanPostProcessors = new ArrayList<>();
public void addBeanPostProcessor(AutowiredAnnotationBeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
public int getBeanPostProcessorCount() {
return this.beanPostProcessors.size();
}
public List<AutowiredAnnotationBeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (AutowiredAnnotationBeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
beanPostProcessor.setBeanFactory(this);
result = beanPostProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
result = beanPostProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
}
- 调整ClassPathXmlApplicationContext
public class ClassPathXmlApplicationContext implements BeanFactory {
AutowireCapableBeanFactory beanFactory;
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
public ClassPathXmlApplicationContext(String fileName){
this(fileName, true);
}
public ClassPathXmlApplicationContext(String fileName, boolean isRefresh) {
Resource res = new ClassPathXmlResource(fileName);
AutowireCapableBeanFactory bf = new AutowireCapableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
reader.loadBeanDefinition(res);
this.beanFactory = bf;
if (isRefresh) {
refresh();
}
}
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
this.beanFactoryPostProcessors.add(postProcessor);
}
@Override
public Object getBean(String beanName) throws BeansException {
return this.beanFactory.getBean(beanName);
}
@Override
public void registerBean(String beanName, Object obj) {
this.beanFactory.registerBean(beanName, obj);
}
@Override
public Boolean containsBean(String name) {
return this.beanFactory.containsBean(name);
}
@Override
public boolean isSingleton(String name) {
return false;
}
@Override
public boolean isPrototype(String name) {
return false;
}
@Override
public Class<?> getType(String name) {
return null;
}
public void refresh() {
onRefresh();
}
private void registerBeanPostProcessors(AutowireCapableBeanFactory bf) {
bf.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
}
private void onRefresh() {
registerBeanPostProcessors(this.beanFactory);
this.beanFactory.refresh();
}
}
测试
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="bbs" class="com.minis.test.BaseBaseService" init-method="init">
<property type="com.minis.test.AServiceImpl" name="as" ref="aservice"/>
</bean>
<bean id="aservice" class="com.minis.test.AServiceImpl">
<constructor-arg type="String" name="name" value="abc"/>
<constructor-arg type="int" name="level" value="3"/>
<property type="String" name="property1" value="Someone says"/>
<property type="String" name="property2" value="Hello World!"/>
<property type="com.minis.test.BaseService" name="ref1" ref="baseservice"/>
</bean>
<bean id="baseservice" class="com.minis.test.BaseService" init-method="init">
</bean>
</beans>
public class BaseService {
@Autowired
private BaseBaseService bbs;
public BaseBaseService getBbs() {
return bbs;
}
public void setBbs(BaseBaseService bbs) {
this.bbs = bbs;
}
public BaseService() {
}
public void sayHello() {
System.out.print("Base Service says hello");
bbs.sayHello();
}
}
ioc2-4.PNG