- 上节已经分析了BeanFactory的实现逻辑,这节主要是具体代码的实现。
二、工程结构
1.代码结构
2.代码
ApplicationContextMainimport pers.bingfeng.bean.BingFengBean; import pers.bingfeng.definition.BeanDefinition; import pers.bingfeng.definition.impl.DefaultFactoryBean; import pers.bingfeng.definition.impl.GenericBeanDefinition; import pers.bingfeng.factory.InstanceFactory; import pers.bingfeng.factory.StaticFactory; public class ApplicationContextMain { public static void main(String[] args) throws Exception { //class类 DefaultFactoryBean dfb = new DefaultFactoryBean(); GenericBeanDefinition clsGenericBeanDefinition = new GenericBeanDefinition() ; clsGenericBeanDefinition.setBeanClass(BingFengBean.class); clsGenericBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); clsGenericBeanDefinition.setInitMethodName("init"); dfb.registryBeanDefinition("classBean",clsGenericBeanDefinition); //静态工厂 GenericBeanDefinition staticGenericBeanDefinition = new GenericBeanDefinition() ; staticGenericBeanDefinition.setBeanClass(StaticFactory.class); staticGenericBeanDefinition.setFactoryMethodName("getBingFengBeanByStatic"); staticGenericBeanDefinition.setInitMethodName("init"); dfb.registryBeanDefinition("staticBean",staticGenericBeanDefinition); //实例工厂 GenericBeanDefinition factoryBeanDefinition = new GenericBeanDefinition() ; factoryBeanDefinition.setBeanClass(InstanceFactory.class); factoryBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); String factoryBeanName = "factory"; dfb.registryBeanDefinition(factoryBeanName,factoryBeanDefinition); GenericBeanDefinition instanceGenericBeanDefinition = new GenericBeanDefinition() ; instanceGenericBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE); instanceGenericBeanDefinition.setFactoryBeanName(factoryBeanName); instanceGenericBeanDefinition.setFactoryMethodName("getByInstanceFactory"); dfb.registryBeanDefinition("instanceBean",instanceGenericBeanDefinition); GenericBeanDefinition instanceSingleton = new GenericBeanDefinition() ; instanceSingleton.setScope(BeanDefinition.SCOPE_SINGLETON); instanceSingleton.setFactoryBeanName(factoryBeanName); instanceSingleton.setFactoryMethodName("getByInstanceFactory"); dfb.registryBeanDefinition("instanceBeanSingleton",instanceSingleton); System.out.println("构造方法开始"); for (int i=0;i<3 ;i++){ BingFengBean classBean = (BingFengBean) dfb.getBean("classBean"); System.out.println(classBean); } System.out.println("静态工厂开始"); for (int i=0;i<3 ;i++){ BingFengBean classBean = (BingFengBean) dfb.getBean("staticBean"); System.out.println(classBean); } System.out.println("实例工厂开始原型"); for (int i=0;i<3 ;i++){ BingFengBean classBean = (BingFengBean) dfb.getBean("instanceBean"); System.out.println(classBean); } System.out.println("实例工厂开始单例"); for (int i=0;i<3 ;i++){ BingFengBean classBean = (BingFengBean) dfb.getBean("instanceBeanSingleton"); System.out.println(classBean); } } }
BingFengBeanpackage pers.bingfeng.bean; public class BingFengBean { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public void init() { System.out.println("BingFengBean.init() 执行了"); } }
BeanDefinitionpackage pers.bingfeng.definition; /** * 为容器提供bean信息。 * */ public interface BeanDefinition { //单例 String SCOPE_SINGLETON = "singleton"; //原型 String SCOPE_PROTOTYPE = "prototype"; Class<?> getBeanClass(); String getScope(); String getFactoryMethodName(); String getFactoryBeanName(); boolean isSingleton(); boolean isPrototype(); String getInitMethodName(); String getDestroyMethodName(); }
BeanDefinitionRegistrypackage pers.bingfeng.definition; public interface BeanDefinitionRegistry { void registryBeanDefinition(String beanName,BeanDefinition bd); BeanDefinition getBeanDefinition(String beanName); boolean containsBeanDefinition(String beanName); }
FactoryBeanpackage pers.bingfeng.definition; import org.apache.commons.lang3.StringUtils; public interface FactoryBean { Object getBean(String name) throws Exception; default boolean validateBeanDefinition(BeanDefinition bd){ if(StringUtils.isNotBlank(bd.getFactoryBeanName()) && bd.getBeanClass() != null){ return false; } if(bd.getBeanClass() ==null ){ if (StringUtils.isBlank(bd.getFactoryBeanName()) || StringUtils.isBlank(bd.getFactoryMethodName())) { return false; } } return true; } }
BeansExceptionpackage pers.bingfeng.definition.exception; public class BeansException extends RuntimeException { public BeansException(String msg) { super(msg); } public BeansException( String msg, Throwable cause) { super(msg, cause); } }
DefaultFactoryBeanpackage pers.bingfeng.definition.impl; import org.apache.commons.lang3.StringUtils; import org.junit.Assert; import pers.bingfeng.definition.BeanDefinition; import pers.bingfeng.definition.BeanDefinitionRegistry; import pers.bingfeng.definition.FactoryBean; import pers.bingfeng.definition.exception.BeansException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class DefaultFactoryBean implements FactoryBean , BeanDefinitionRegistry { private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); private Map<String, Object> beanMap = new ConcurrentHashMap<>(); @Override public Object getBean(String beanName) throws Exception { return doGetBean(beanName); } private Object doGetBean(String beanName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Assert.assertNotNull(beanName); Object beanInstance = beanMap.get(beanName); if (null != beanInstance){ return beanInstance; } BeanDefinition beanDefinition = this.getBeanDefinition(beanName); Assert.assertNotNull(beanDefinition); //获取class对象 Class<?> cls = beanDefinition.getBeanClass(); //class不为空,则是构造和静态工厂。 if(cls != null ){ if(StringUtils.isBlank(beanDefinition.getFactoryMethodName())){ beanInstance = createInstanceByConstructor(cls); }else { beanInstance = createInstanceByStaticFactory(beanDefinition,cls); } }else { //实例工厂实现 beanInstance = createInstanceByInstanceFactory(beanDefinition); } //初始化 this.doInitMethod(beanDefinition,beanInstance); if(beanDefinition.isSingleton()){ beanMap.put(beanName,beanInstance); } return beanInstance; } private void doInitMethod(BeanDefinition beanDefinition,Object beanInstance) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { String initMethodName = beanDefinition.getInitMethodName(); if(StringUtils.isNotBlank(initMethodName)){ Method method = beanInstance.getClass().getMethod(initMethodName); method.invoke(beanInstance); } } @Override public void registryBeanDefinition(String beanName, BeanDefinition bd) { //beanName不能为空 Assert.assertNotNull(beanName); Assert.assertNotNull(bd); if(this.containsBeanDefinition(beanName)){ throw new BeansException("beanName 已经注册过了"); } if(!validateBeanDefinition(bd)){ throw new BeansException( beanName + "的beanDefinition 不和法"); } beanDefinitionMap.put(beanName,bd); } @Override public BeanDefinition getBeanDefinition(String beanName) { return this.beanDefinitionMap.get(beanName); } @Override public boolean containsBeanDefinition(String beanName) { return beanDefinitionMap.get(beanName) != null; } private Object createInstanceByConstructor(Class cls){ try { return cls.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } private Object createInstanceByStaticFactory(BeanDefinition bd ,Class cls) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { String factoryMethodName = bd.getFactoryMethodName(); Method method = cls.getMethod(factoryMethodName); return method.invoke(cls); } private Object createInstanceByInstanceFactory(BeanDefinition bd ) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { //获取工厂beanFactoryName String factoryBeanName = bd.getFactoryBeanName(); //根据BeanName获取工厂对象 Object beanFactory = doGetBean(factoryBeanName); //获取工厂名称 String factoryMethodName = bd.getFactoryMethodName(); Method factoryMethod = beanFactory.getClass().getMethod(factoryMethodName); return factoryMethod.invoke(beanFactory); } }
GenericBeanDefinitionpackage pers.bingfeng.definition.impl; import org.apache.commons.lang3.StringUtils; import pers.bingfeng.definition.BeanDefinition; public class GenericBeanDefinition implements BeanDefinition { //beanclass private Class<?> beanClass; //工厂bean private String factoryBeanName; private String factoryMethodName; private String scope = BeanDefinition.SCOPE_SINGLETON; private String initMethodName; private String destroyMethodName; public void setBeanClass(Class<?> beanClass) { this.beanClass = beanClass; } public void setFactoryBeanName(String factoryBeanName) { this.factoryBeanName = factoryBeanName; } public void setFactoryMethodName(String factoryMethodName) { this.factoryMethodName = factoryMethodName; } public void setScope(String scope) { if(StringUtils.isNotBlank(scope)){ this.scope = scope; } } public void setInitMethodName(String initMethodName) { this.initMethodName = initMethodName; } public void setDestroyMethodName(String destroyMethodName) { this.destroyMethodName = destroyMethodName; } @Override public Class<?> getBeanClass() { return this.beanClass; } @Override public String getScope() { return this.scope; } @Override public String getFactoryMethodName() { return this.factoryMethodName; } @Override public String getFactoryBeanName() { return this.factoryBeanName; } @Override public boolean isSingleton() { return BeanDefinition.SCOPE_SINGLETON.equals(this.scope); } @Override public boolean isPrototype() { return BeanDefinition.SCOPE_PROTOTYPE.equals(this.scope); } @Override public String getInitMethodName() { return initMethodName; } @Override public String getDestroyMethodName() { return destroyMethodName; } }
- InstanceFactory
package pers.bingfeng.factory; import pers.bingfeng.bean.BingFengBean; public class InstanceFactory { public BingFengBean getByInstanceFactory(){ return new BingFengBean(); } }
StaticFactorypackage pers.bingfeng.factory; import pers.bingfeng.bean.BingFengBean; public class StaticFactory { public static BingFengBean getBingFengBeanByStatic(){ return new BingFengBean(); } }
1.测试结果:
构造方法开始
BingFengBean.init() 执行了
pers.bingfeng.bean.BingFengBean@6f94fa3e
pers.bingfeng.bean.BingFengBean@6f94fa3e
pers.bingfeng.bean.BingFengBean@6f94fa3e
静态工厂开始
BingFengBean.init() 执行了
pers.bingfeng.bean.BingFengBean@66d3c617
pers.bingfeng.bean.BingFengBean@66d3c617
pers.bingfeng.bean.BingFengBean@66d3c617
实例工厂开始原型
pers.bingfeng.bean.BingFengBean@2b193f2d
pers.bingfeng.bean.BingFengBean@355da254
pers.bingfeng.bean.BingFengBean@4dc63996
实例工厂开始单例
pers.bingfeng.bean.BingFengBean@d716361
pers.bingfeng.bean.BingFengBean@d716361
pers.bingfeng.bean.BingFengBean@d716361