用工厂模式+反射对依赖注入做个探究

概述

创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象的模式叫工厂模式,结合以前学的反射来对依赖注入做个简单的探究

大体思路是有一个实体BeanDefinition记录类的信息,而XmlBeanConfigParser负责解析xml文件,并将实体信息传给BeansFactory,BeansFactory根据实体信息创建相应的对象,如图
在这里插入图片描述

demo

ClassPathXmlApplication类:

public class ClassPathXmlApplication {

    private BeansFactory beansFactory;
    private XmlBeanConfigParser beanConfigParser;

    public ClassPathXmlApplication(String config){

        this.beansFactory = new BeansFactory();
        this.beanConfigParser = new XmlBeanConfigParser();
        loadBeanDefinition(config);

    }

    private void loadBeanDefinition(String config) {

        InputStream in = null;

        try {
            in = this.getClass().getResourceAsStream("/"+config);
            if (in == null){
                throw new RuntimeException("can not find config file:"+config);
            }
            List<BeanDefinition> beanDefinitions = beanConfigParser.parse(in);

            beansFactory.addBeanDefinitions(beanDefinitions);

        } catch (DocumentException e) {
            e.printStackTrace();
        }finally {
            if (in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Object getBean(String beanId){
        return beansFactory.getBean(beanId);
    }

    public static void main(String[] args) {

        ClassPathXmlApplication xmlApplication = new ClassPathXmlApplication("beans.xml");
        Person person = (Person) xmlApplication.getBean("person");
        System.out.println(person);

    }

}

XmlBeanConfigParser 类:解析xml配置文件,生成BeanDefinition的List传给BeanFactory

public class XmlBeanConfigParser {


    public List<BeanDefinition> parse(InputStream inputStream) throws DocumentException {

        List<BeanDefinition> beanDefinitions = new ArrayList<>();

        SAXReader reader = new SAXReader();;
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();

        Iterator<Element> it=root.elementIterator("bean");
        while (it.hasNext()){

            BeanDefinition beanDefinition = new BeanDefinition();
            Element child = it.next();

            Iterator<Attribute> attribute = child.attributeIterator();
            while(attribute.hasNext()) {

                Attribute attr =  attribute.next();
                if ("id".equalsIgnoreCase(attr.getName())){
                    beanDefinition.setId(attr.getValue());
                }

                if ("class".equalsIgnoreCase(attr.getName())){
                    beanDefinition.setClassName(attr.getValue());
                }

            }

            beanDefinitions.add(beanDefinition);

        }

        return  beanDefinitions;

    }

}

BeansFactory:把解析过来的

List<BeanDefinition> beanDefinitionList

存到一个Map对象中,需要的时候从Map中拿

public class BeansFactory {

    private ConcurrentHashMap<String, BeanDefinition> beanDefinitions = new ConcurrentHashMap<>();


    public void addBeanDefinitions(List<BeanDefinition> beanDefinitionList){

        for (BeanDefinition bean:beanDefinitionList) {

            this.beanDefinitions.put(bean.getId(),bean);

        }

    }

    public Object getBean(String beanId){
        
         BeanDefinition beanDefinition = beanDefinitions.get(beanId);
        
         if (beanDefinition==null){
             
             throw new NoSuchBeanDefinitionException("没有这个bean类");
             
         }
         //创建类
        return createBean(beanDefinition);
}

    private Object createBean(BeanDefinition beanDefinition) {

        Object bean = null;

        try {
            Class beanClass = Class.forName(beanDefinition.getClassName());

            bean = beanClass.newInstance();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return bean;
    }
}

BeanDefinition:保存xml中bean对象的信息

public class BeanDefinition {

    private String id;
    private String className;

    public void setId(String id) {
        this.id = id;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getId() {
        return id;
    }

    public String getClassName() {
        return className;
    }
}

测试一下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值