spring中的工厂模式
案例1:实现一个工厂类
当前的工厂类,通过属性文件中的名称进行创建对象
第一步:配置属性文件bean.properties
## 语法 :值 = 类路径 UserDao = com.jie.dao.UserDao UserDaoImpl = com.jie.dao.impl.UserDaoImpl UserService = com.jie.service.UserService UserServiceImpl = com.jie.service.impl.UserServiceImpl
注意:使用以上配置的时候,需要将配置文件中的路径在java的spring项目中进行创建一个class与之(类路径)匹配
其他包下的一些类
Dao层下
interface
package com.jie.dao;
public interface UserDao {
// 增
public void addUser();
// 删
public void deleteUser();
// 改
public void updateUser();
// 查
public void queryUser();
}
Dao层下的impl包
package com.jie.dao.impl;
import com.jie.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println(" add user ");
}
@Override
public void deleteUser() {
System.out.println(" delete user ");
}
@Override
public void updateUser() {
System.out.println( " update user " );
}
@Override
public void queryUser() {
System.out.println(" query user ");
}
}
service层下
package com.jie.service;
public interface UserService {
public void addService();
public void deleteSerevice();
public void upateSersvice();
public void queryService();
}
impl包
package com.jie.service.impl;
import com.jie.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public void addService() {
System.out.println(" add is service ");
}
@Override
public void deleteSerevice() {
System.out.println(" delete is service ");
}
@Override
public void upateSersvice() {
System.out.println(" update is service ");
}
@Override
public void queryService() {
System.out.println(" query is service ");
}
}
第二步:创建一个工厂类
package com.jie.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
// 工厂类
// 作用:
// 1. 加载配置文件
// 2. 生产配置文件中配置的类
public class MyFactory {
// 获取属性文件的对象
private Properties properties = new Properties();
// 构造方法
// 1. 在当前的构造方法中:通过路径(属性文件bean.properties)获取了一个当前属性文件的流
// 2. 通过获取的properties流进行加载当前的属性文件
public MyFactory( String propertiesPath) throws IOException {
// properties中的load方法中加载的需要一个流
InputStream resourceAsStream = MyFactory.class.getResourceAsStream(propertiesPath);
// 使用当前的properties对象读取的是当前配置文件中的信息
properties.load(resourceAsStream);
}
// getBean 生产对象
public Object getBean( String name ) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 通过当前的name获取当前的类路径
String classPath = properties.getProperty(name);
// 通过反射创建对象
Class clazz = Class.forName(classPath);
return clazz.newInstance();
}
}
描述当前工厂类的主要功能
-
加载配置文件(bean.properties)
<主要在构造方法中实现>
-
-
在工厂类中的构造方法中,使用 java.util.Properties的类对象的load方法加载属性文件
-
而proerties.load(流)需要一个流
(1)获取流对象
MyFactory.class.getResourceAsStream("/bean.properties");
(2)将获取的流对象传入load方法中进行加载properties属性文件
-
-
-
生产配置文件中(bean.properties)的类对象
<主要在getBean方法中实现>
-
使用properties对象的getproperties(name)获取的name名字的类路径
String classPath = properties.getProperty(name)
-
通过反射创建对象(生产bean) Class clazz = Class.forName(classPath);
-
返回通过反射创建的类的实例
return clazz.newInstance();
-
第三步:测试类测试
package com.jie.test;
import com.jie.dao.UserDao;
import com.jie.dao.impl.UserDaoImpl;
import com.jie.factory.MyFactory;
import java.io.IOException;
public class FactoryTest {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// 创建工厂对象
MyFactory myFactory = new MyFactory("/bean.properties);
// 一下的这个代码会报错
// 1. 我们在dao层中将当前的这个userDao的类的对象改写成了interfacce 所以
// 在我们继续使用当前的工厂类进行创建对象的时候,会通过采用java反射的方式进行生产对象
// 使用反射生产对象的时候就会拿到当前的反射的那个interface的路径,并不是一个类
// 因为interface中都是抽象方法并没有实现方法。 所以会报出一个NoSuchMethodException的异常
// UserDao userDao = (UserDao) myFactory.getBean("UserDao");
UserDaoImpl userDaoImpl = (UserDaoImpl)myFactory.getBean("UserDaoImpl");
userDaoImpl.deleteUser();
}
}
测试类中的注意点:
当前测试类中使用的是:工厂类中的getBean(name)的方法生产对象
参数:name 就是属性文件中的properties中的指定的名字
而测试中的类如果是一个interface(接口) 那么就是报出一个异常
NoSuchMethodException,因为interface(接口)中没有实现方法,只有抽象方法,所以会报出错误。
文章介绍了如何在Spring中使用工厂模式,通过属性文件bean.properties配置类路径,然后在工厂类中加载属性文件并使用反射创建对象。在测试类中,通过工厂类的getBean方法获取对象,如果尝试从接口获取对象则会抛出异常,因为接口没有实现方法。






