Java中通过修改配置文件实现接口或抽象类子类的切换

我们开发的项目中有可能针对不同的数据库,因此同一个Dao接口可能提供了针对不同数据库的实现。下面我们通过修改properties配置文件的方式来实现同一个接口调用不同子类的实现,这样我们不用去修改源代码,只需要修改配置文件就可以实现调用不同的子类中的方法。该博客参考自《黑马JavaEE12期》。

具体的代码如下:

1、第一步:创建一个普通的Java Project
Java中通过修改配置文件实现接口或抽象类子类的切换_第1张图片

2、定义一个接口A和A接口的两个实现类
①A接口定义如下

package cn.itcast.jaxp.demo;

public interface A {
    void show();
}

②A接口的第一个实现类定义如下

package cn.itcast.jaxp.demo;

public class Aimpl1 implements A {

    public void show() {
        System.out.println("这是A接口的第一个实现类");
    }

}

③B接口的第二个实现类如下

package cn.itcast.jaxp.demo;

public class Aimpl2 implements A {

    public void show() {
        System.out.println("这是B接口的第二个实现类");
    }

}

3、定义一个抽象类B和B的两个子类
①抽象类B定义如下

package cn.itcast.jaxp.demo;

public abstract class B {
    abstract void eat();
}

②B的第一个子类定义如下

package cn.itcast.jaxp.demo;

public class Bimpl1 extends B {

    @Override
    public void eat() {
        System.out.println("这是抽象类B的第一个实现类");
    }

}

③B的第二个子类定义如下

package cn.itcast.jaxp.demo;

public class Bimpl2 extends B {

    @Override
    public void eat() {
        System.out.println("这是抽象类B的第二个实现类");
    }

}

4、定义一个properties文件,beanFactory.properties中的代码如下

#key是接口或抽象类简单名,value是具体的子类名(全名)
A=cn.itcast.jaxp.demo.Aimpl1
B=cn.itcast.jaxp.demo.Bimpl1

5、定义读取beanFactory.properties的工具类,BeanFactory.java中的代码如下

package cn.itcast.jaxp.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

/**
 * 工具类
 */
public class BeanFactory {

    private static Properties prop = new Properties();

    //将加载写到静态代码块中,只用加载一次
    static{
        try {
            //1、加载配置文件
            prop.load(new FileInputStream("src/beanFactory.properties"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用泛型实现通用
     * @param c
     * @return
     */
    public static  T getBean(Class c) {
        try {
            //2、取出用哪个实现类,c.getSimpleName()会返回类名(不含包名)
            String className = prop.getProperty(c.getSimpleName());
            //3、根据完整类名创建实例并返回
            @SuppressWarnings("unchecked")
            Class clazz = (Class) Class.forName(className);
            return clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

}

6、编写测试类,Test.java中的代码如下

package cn.itcast.jaxp.demo;

public class Test {

    public static void main(String[] args) {
        //创建一个A后代的实例
        A a = BeanFactory.getBean(A.class);
        a.show();
        //创建一个B后代的实例
        B b = BeanFactory.getBean(B.class);
        b.eat();
    }

}

7、运行Test.java,控制台打印如下内容

这是A接口的第一个实现类
这是抽象类B的第一个实现类

修改beanFactory.properties中value值如下:

#key是接口或抽象类简单名,value是具体的子类名(全名)
A=cn.itcast.jaxp.demo.Aimpl2
B=cn.itcast.jaxp.demo.Bimpl2

运行Test.java,控制台打印如下内容:

这是B接口的第二个实现类
这是抽象类B的第二个实现类

你可能感兴趣的:(java)