Spring学习( 一 ):程序的解耦和自己设计一个BeanFactory
前言
我们在学习完工厂模式之后,发现网上给的例子,根本体现不了工厂模式的作用。先不说存在有的例子本身就是错误的,主要是例子中的代码太简单,可以说没必要用工厂模式,只不过是为了说明实现方式和原理。所以,会产生一种错觉:还不如直接new 一个对象来的方便,有效。
一、介绍一下工厂模式(重点)
我们先介绍一下工厂模式的好处,然后再开始用简单的例子来演示工厂模式的实现。
1、工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。
2、工厂模式能减少大量重复代码,如果A类要使用B,如果创建B的过程很复杂,且很多类都使用B,那么会产生大量重复代码。如果这个时候要把B改为B的子类,那么要在很多地方修改创建类的方法
3、很多时候单例已经能满足程序的需求,那么通过 new 创建出来的类是多例,降低了程序的性能。
所以工厂模式能解决这么多问题,我们为什么还要使用new呢?
二、工厂模式的演示
2、创建application.properties 里面存beanName和类名全路径
userService=com.service.impl.UserServiceImpl
userDao=com.dao.impl.UserDapImpl
2、创建一个BeanFactory
这个工厂创建出来的不是单例对象,后面还要做改造。
public class BeanFactory {
private static Properties properties;
// 1、通过静态代码块对Properties初始化
static {
try {
properties = new Properties();
// 2、获取properties的文件流
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("application.properties");
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object getBean(String beanName){
Object bean = null;
try {
// 通过beanName获取类名全路径
String property = properties.getProperty(beanName);
bean = Class.forName(property).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
3、测试
public class UserController {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
UserService bean = (UserService) BeanFactory.getBean("userService");
System.out.println(bean);
System.out.println(bean.getUser("张三"));
}
}
}
可以看到每个对象都不一样,所以说多例。
4、改造成单例工厂
创建一个容器(Map)key为beanName,value为创建出来的实例。这样每次从HashMap拿到的对象都是同一个。
public class BeanFactory {
private static Properties properties;
private static Map<String,Object> beans;
// 通过静态代码块对Properties初始化
static {
try {
properties = new Properties();
beans = new HashMap<>();
// 2、获取properties的文件流
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("application.properties");
properties.load(inputStream);
Enumeration<Object> keys = properties.keys();
while (keys.hasMoreElements()){
String beanName = (String) keys.nextElement();
String className = properties.getProperty(beanName);
Object bean = Class.forName(className).newInstance();
beans.put(beanName,bean);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getBean(String beanName){
return beans.get(beanName);
}
}
5、写在最后
本文代码已上传到GitHub上面了,需要请直接私信我。