实现Bean工厂

1 Bean工厂的作用

一开始,我写好了类1.1(定义接口+实现接口),我在类2中需要使用类1.1的功能,那么最简单的方法就是在类2中创建类1的对象,然后调用类1的方法(直接使用类1的静态方法另当别论)
后来,类1.1的功能需要增强才能满足新的需求了,要么直接修改类1.1,如果不想动类1.1,那就新建一个接口的实现类1.2
于是在类2中,又重新的创建类1.2的对象,使用类1.2新增的方法
上面的做法,虽然也很方便,但是问题在于“需要修改源代码”,至少需要在类2中重新创建新的需要使用的对象
如果要想不修改源码,就不能让类2去直接创建要使用的对象,否则被使用的对象一旦修改,那么类2中的源码一定也要改
于是,为了解除类与类之间的耦合性,我们选择构建一个“工厂”
类2不再直接创建要使用的对象,而是委托“工厂”来创建,委托的凭证就是“要使用的对象的接口”
类2通过调用工厂的方法,传入“要使用的对象的接口”,直接获取要使用的对象的实现类
而工厂在拿到“要使用的对象的接口”这个参数之后,从配置文件中找到该接口所对应的实现类的全类名,然后通过反射创建对象出来返回给调用者
以上便是Bean工厂的作用

2 Bean工厂的实现

该方法传入一个接口的名字,该类根据这个名字,从配置文件中找到对应的实现类
将该实现类创建出来返回给被调用者
该方法的参数为:目标接口的class对象
Class类有个方法:getSimpleName 获取class对象的简单名字
该方法是静态方法,且用到泛型编程,因为不确定返回的对象的具体类型

public class BeanFactory {
    
    public static <T> T getInstance(Class<T> cla) {
        T obj = null;
        try {
            //获取接口的名字
            String simpleName = cla.getSimpleName();
            //读取配置文件,将接口名作为键,查询接口的全类名
            ResourceBundle bundle = ResourceBundle.getBundle("bean");
            String className = bundle.getString(simpleName);
            //反射,获取全类名对应的class对象,利用class对象创建实际需要的对象,返回
            Class<?> aClass = Class.forName(className);
            obj = (T)aClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

3 使用Bean工厂

  • 定义接口:UserService
public interface UserService {
    void register();
}
  • 定义接口的实现类:UserServiceImpl1、UserServiceImpl2
public class UserServiceImpl implements UserService {

    @Override
    public void register() {
        System.out.println("方法1.1");
    }
}
public class UserServiceImpl2 implements UserService {
    @Override
    public void register() {
        System.out.println("方法1.2");
    }
}
  • 在配置文件中写清楚“接口名”和“实现类全类名”的对应关系
UserService=com.lmy.service.impl.UserServiceImpl #表明此时使用Impl这个实现类,而是不是Impl2
  • 使用Bean工厂创建并使用对象的功能
public class Servlet {
    public void doGet(){
        /**
         * 我不想new一个对象出来,而是使用“工厂”让他替我去创建那个我需要的对象,而我只是去使用这个对象
         * web层获取业务层接口实现类不能New,而是通过BeanFactory获取
         * 于是,在web层中,调用BeanFactory的方法,传递需要的业务层方法所对应的接口,方法返回实现类对象
         */
        UserService userService = BeanFactory.getInstance(UserService.class);
        userService.register();
    }
}

最终,控制台上会显示“方法1.1”,而不是“方法1.2”,如果要使用“方法1.2”只需要把配置文件中的全类名修改即可,不需要修改任何的源代码!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值