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(接口)中没有实现方法,只有抽象方法,所以会报出错误。