通过反射创建对象,尽量少的使用new()创建对象是降低类与类之间耦合度方法,我们先来看看工厂模式创建对象的一个简单的实例
首先创建一个UserDao接口
package com.lp.dao;
/**
* @Date 2020/5/26 21:19
* @Author luopeng
*/
public interface UserDao {
void saveUser();
}
创建接口实现类
package com.lp.dao.impl;
import com.lp.dao.UserDao;
import com.lp.factory.Factory;
/**
* @Date 2020/5/26 21:20
* @Author luopeng
*/
public class UserDaoImpl implements UserDao {
public void saveUser() {
System.out.println("保存成功!");
}
}
service层接口
package com.lp.service;
/**
* @Date 2020/5/26 21:18
* @Author luopeng
*/
public interface UserService {
void saveUser();
}
接口实现类
package com.lp.service.impl;
import com.lp.dao.UserDao;
import com.lp.dao.impl.UserDaoImpl;
import com.lp.factory.Factory;
import com.lp.service.UserService;
/**
* @Date 2020/5/26 21:21
* @Author luopeng
*/
public class UserServiceImpl implements UserService {
public void saveUser() {
UserDao userDao = Factory.getBean("userDao");
userDao.saveUser();
}
}
创建工厂类实现反射创建对象
package com.lp.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @Date 2020/5/26 21:25
* @Author luopeng
*/
public class Factory {
private static Properties pro = new Properties();
static {
try {
InputStream inputStream = Factory.class.getClassLoader().getResourceAsStream("bean.properties");
pro.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static <T> T getBean(String beanName) {
String property = pro.getProperty(beanName);
Object newInstance = null;
try {
//通过反射创建对象
newInstance = Class.forName(property).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) newInstance;
}
}
写测试类
package com.lp.ui;
import com.lp.factory.Factory;
import com.lp.service.UserService;
/**
* @Date 2020/5/26 21:21
* @Author luopeng
*/
public class test {
public static void main(String[] args) {
for (int j = 0; j <5 ; j++) {
UserService userService = Factory.getBean("userService");
userService.saveUser();
System.out.println(userService);
}
}
}
运行后的结果截图
此时我们会发现每次程序都会新创建对象,这显然是一个多例,而对于我们此时来讲,为了提高程序的效率,我们更愿意是单例的,此时我们需要对工厂类进行重新设计!
- 首先讲一下想法和思路:对于配置文件中的信息,我们需要创建对象来供使用,我的方法是通过一个Map集合来将对象存储在里面,需要用这个对象时只需要传入key即可。
- 我们怎么来创建对象呢?首先我们需要把配置文件中的key拿到,我有两种方法来拿,keys()和keyset(),过程大同小异,代码中两种方式我都有写。
- 拿到了过后我们需要的是遍历拿到的key,然后通过key来得到其value,通过反射来创建对象,将创建的对象存在我们定义好的容器Map中。
- 这些操作我们在静态代码块中进行操作,即类一加载就创建好对象,且只创建一次,最后要用的时候从容器里面取出来就行了!
package com.lp.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* @Date 2020/5/26 21:25
* @Author luopeng
*/
public class Factory {
private static Properties pro;
private static Map<String, Object> beans;
static {
try {
pro = new Properties();
InputStream inputStream = Factory.class.getClassLoader().getResourceAsStream("bean.properties");
pro.load(inputStream);
//实例化容器
beans = new HashMap<String, Object>();
//取出配置文件中的key
/* Set<Object> keys = pro.keySet();
//遍历取出每一个key
for (Object key : keys) {
//根据key从配置文件中取得value(即类路径)的值
String classPath = pro.getProperty((String) key);
//通过反射创建对象
Object value = Class.forName(classPath).newInstance();
//将key和value存入我们的容器里面
beans.put((String) key, value);
}*/
Enumeration<Object> keys = pro.keys();
//遍历取出每一个key
while (keys.hasMoreElements()) {
String key = keys.nextElement().toString();
//根据key从配置文件中取得value的值
String classPath = pro.getProperty(key);
//通过反射创建对象
Object value = Class.forName(classPath).newInstance();
//将key和value存入我们的容器里面
beans.put((String) key, value);
}
} catch(IOException e){
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static <T > T getBean(String beanName) {
/* String property = pro.getProperty(beanName);
Object newInstance = null;
try {
//通过反射创建对象
newInstance = Class.forName(property).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) newInstance;*/
return (T) beans.get(beanName);
}
}