======== 反射工厂 ======== 1 对象的创建方式 在Java中一共有两种创建对象的方式: - 直接调用对象的构造方法创建对象 UserDao userDao = new UserDaoImpl(); 直接使用了实现类的类型,发生类型间的强耦合 - 利用反射机制创建对象 UserDao userDao = (UserDao) Class.forName( "cn.tedu.reflectionfactory.UserDaoImpl").newInstance(); 只使用实现类的类名而不使用其类型,避免了类型间的耦合 2 在工厂类中以反射的方式创建实现类对象 /src/main/java/cn/tedu/reflectionfactory/BeanFactory.java: public class BeanFactory { public static UserDao getUserDao() { UserDao userDao = null; try { userDao = (UserDao) Class.forName( "cn.tedu.reflectionfactory.UserDaoImpl").newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return userDao; } public static UserService getUserService() { UserService userService = null; try { userService = (UserService) Class.forName( "cn.tedu.reflectionfactory.UserServiceImpl").newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return userService; } } 例程:ReflectionFactory - 工厂类和实现类之间的类型耦合虽然解除了,但实现类的全限定名仍然出现在工厂类的代码中 - 实现类的全限定名如果发生变化,工厂类的代码仍不得不修改 - 耦合解除得不够彻底 - 解决字符串(权限定类名)耦合比解决类型耦合容易得多 3 在配置文件中书写实现类的全限定名 将实现类的全限定名字符串放到一个配置文件中。 /src/main/resources/applicationContext.properties: userDao = cn.tedu.reflectionfactory.UserDaoImpl userService = cn.tedu.reflectionfactory.UserServiceImpl 4 在工厂类中从配置文件中获取实现类的全限定名 /src/main/java/cn/tedu/reflectionfactory/BeanFactory.java: public class BeanFactory { private static Properties properties = new Properties(); static { try { InputStream inputStream = BeanFactory.class.getResourceAsStream( "/applicationContext.properties"); properties.load(inputStream); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static UserDao getUserDao() { UserDao userDao = null; try { userDao = (UserDao) Class.forName( properties.getProperty("userDao")).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return userDao; } public static UserService getUserService() { UserService userService = null; try { userService = (UserService) Class.forName( properties.getProperty("userService")).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return userService; } } 例程:ReflectionFactory - 工厂类中既不使用实现类的类型,也不使用实现类的全限定名 - 实现类改变了,顶多也就是改改配置文件,Java代码彻底解耦