实现一个对象工厂

用一个对象工厂创建出来的对象,并且是单例的。

工厂类用枚举类,资源文件beans.properties中按照这样的格式写,key为所要创建的对象,value为类的全限定名称

#name=className
productDAO=dao.impl.ProductDAOImpl
productService=service.impl.ProductServiceImpl

先加载资源文件,用一个Map充当缓存(缓存中存在直接取出,没有再去创建对象). 用getBean方法来获取对象,两个参数分别为:所要创建对象的名称(与资源文件中的key对应)、对象所实现接口的类型(IXxx.class)

public enum BeanFactoy {
    INSTANCE;

    private static Properties p = new Properties();
    private Map<String, Object> cache = new HashMap<>();
    static {// 加载资源文件
        InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("beans.properties");
        try {
            p.load(inStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 传递的参数等于资源文件中的key
    @SuppressWarnings("unchecked")
    public <T> T getBean(String beanName, Class<T> requiredType) {
        // 判断缓存中是否存在指定名称的对象
        Object current = cache.get(beanName);
        if (current == null) {
            String className = p.getProperty(beanName);// 得到类的权限顶名称
            if (className != null) {
                try {
                    Object obj = Class.forName(className).newInstance();
                    if (!requiredType.isInstance(obj)) {//判断obj是否为requireType的实例
                        throw new RuntimeException("类型不正确");
                    }
                    cache.put(beanName, obj);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return (T) cache.get(beanName);
    }

    public static void main(String[] args) {
        IProductDAO dao1 = BeanFactoy.INSTANCE.getBean("productDAO", IProductDAO.class);
        IProductDAO dao2 = BeanFactoy.INSTANCE.getBean("productDAO", IProductDAO.class);
        System.out.println(dao1);
        System.out.println(dao2);// 相等. 说明是单例的
    }
}
posted @ 2019-01-20 16:46 earth腾飞 阅读(...) 评论(...) 编辑 收藏