1、程序间的依赖关系问题
我们在用jdbc方式获取conn的时候有这两种写法:
DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //注册驱动
Connection conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost3306/test","root","root");
//第二种
Class.forName("com.mysql.jdbc.Driver");
而我们在用的时候都会用第二种从来不用第一种,为什么?因为第一种方式属于编译依赖,也就是说如果com.mysql.jdbc.Driver类不存在的时候,代码直接编译不通过,而第二种则不会,可以正常编译,只不过会让你捕获一下异常,如果在运行时确实找不到这个类,才会报错,这属于运行时依赖。在我们正常开发中经常会碰到有依赖关系的不同功能由不同人开发,这时候如果我们写的代码是编译依赖的话,那你只有等人家代码写完了你再写。。
2、说完依赖的问题,想想我们以前的三层架构new 对象的方式
IServiceCustomer serviceCus = new ServiceCustomerImpl();
这就是典型的编译依赖,所以我们得改变一下写法,用反射的方式去获取实例,考虑到会获取很多实例,所以我们弄一个BeanFactory类专门来写方法获取各种实例:
public class BeanFactory{
public static ICustomerService getCustomerService(){
try{
return (ICustomerService) Class.forName(com.dimples.service.impl.CustomerServiceImpl").newInstance();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
写到这里,我们还会觉得每获取一个实例就写一个方法还是太繁杂,所以我们选择写一个方法,然后创建一个properties配置文件:
BeanFactory我们可以这么写:
public class BeanFactory{
private static ResourceBundle bundle = null;
static{
bundle = ResourceBundle.getBundle("com.dimples.test.bean");
}
public Object getAllInstance(String name){
String completeName = bundle.get(name);
return Class.forName("completeName").newInstance();
}
}
接下来介绍两种读取properties文件方式,第一种Properties方式获取
package com.dimples.test;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Test1 {
private static Properties pro = new Properties();
static {
//这种类加载器获取in的方式,properties只能放在类路径下,比如放在com.dimples.test包下了那就"com/dimples/test/bean.properties"
//还要注意一点的是这种方式获取properties文件,文件一定要放在类路径下!!
InputStream in = Test1.class.getClassLoader().getResourceAsStream("bean.properties");
//这种方式获取in的方式,是不能使用的!!!因为web工程发布以后没有src路径了,所以这句话会找不到文件。
//InputStream in = new FileInputStream("src/bean.properties");
System.out.println(in);
//这里注意try catch中的一个小细节:try语句块中报错了,不一定就会跳进catch,要看你catch的异常有没有包括try产生的异常,如下面这个try中pro为null,那么会抛空指针异常,而不会进入catch语句块。
try {
pro.load(in);
} catch (IOException e) {
System.out.println("load出错了");
}
}
public static void main(String[] args) {
System.out.println(pro.get("user"));
}
}
第二种使用bundle
package com.dimples.test;
import java.util.ResourceBundle;
public class Test2 {
//ResourceBundle是专门用于读取properties文件的类,别的读不了
//也正因为是properties专属,所以getBundle()参数不需要写.properties
//它只用于读取,不能写入,而Properties可以
//点进去看这个方法我们发现它用到了类加载器,所以这种方式properties文件也只能写在类路径下,如在类根路径下就直接"bean",如在包下就"com.dimples.test.bean"
private static ResourceBundle bundle = ResourceBundle.getBundle("com.dimples.test.bean");
public static void main(String[] args) {
String user = bundle.getString("user");
System.out.println(user);
}
}