耦合:耦合指的就是对象之间的依赖关系。对象之间的耦合越高,维护成本越高。
案例:没有引入IOC容器时系统的Web层、业务层、持久层存在耦合
/**
* 持久层实现类
*/
public class UserDaoImpl implements UserDao {
@Override
public void addUser(){
System.out.println("insert into tb_user......");
}
}
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
//硬编码:此处有依赖关系
private UserDao userDao = new UserDaoImpl();
public void addUser(){
userDao.addUser();
}
}
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
//硬编码:此处有依赖关系
UserService userService = new UserServiceImpl();
userService.addUser();
}
}
问题分析:
上边的代码service层在依赖dao层的实现类,此时如果更改dao了层的实现类或此时没有dao层实现类,编译将不能通过。
IOC(工厂模式)解耦:
把所有的dao和service对象使用配置文件配置起来
当服务器启动时读取配置文件
把这些对象通过反射创建出来并保存在容器中
在使用的时候,直接从工厂拿
?案例一
/**
* bean工厂
*/
public class BeanFactory_v1 {
/**
* 获得UserServiceImpl对象
* @return
*/
public static UserService getUserService(){
return new UserServiceImpl();
}
/**
* 获得UserDaoImpl对象
* @return
*/
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
问题:我们在开发中会有很多个service和dao,此时工厂类就要添加无数个方法。
案例二
#1、配置要使用的dao和service
UserDao=com.by.dao.UserDaoImpl
UserService=com.by.service.UserServiceImpl
/**
* bean工厂
*/
public class BeanFactory_v2 {
private static Properties prop = new Properties();
/**
* 根据全类名获取bean对象
* @param beanName
* @return
* @throws ClassNotFoundException
*/
public static Object getBean(String beanName) {
try {
//不能使用:web工程发布后没有src目录
//InputStream is = new FileInputStream("src/bean.properties");
InputStream is =
BeanFactory_v2.class.getClassLoader()
.getResourceAsStream("bean.properties");
prop.load(is);
return Class.forName(prop.getProperty(beanName)).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(prop.get("UserService"));
System.out.println(getBean("UserService"));
}
}
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = (UserDao) BeanFactory.getBean("UserDao");
public void addUser(){
userDao.addUser();
}
}
测试:
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
//直接引用接口实现类
for (int i = 0; i < 5; i++) {
UserService userService =
(UserService)BeanFactory.getBean("UserService");
System.out.println(userService);
}
}
}
问题:
每次都会创建新的对象
程序运行时才创建对象(读取配置文件)
案例三
package com.by.factory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* bean工厂
*/
public class BeanFactory_v3 {
//定义一个容器,用于存放对象
private static Map<String, Object> beans = new HashMap<>();
/**
* 加载配置文件
*/
static {
try {
//2、读取配置文件
//不能使用:web工程发布后没有src目录
//InputStream is = new FileInputStream("src/bean.properties");
InputStream is =
BeanFactory_v3.class.getClassLoader()
.getResourceAsStream("bean.properties");
//3、通过反射创建对象,把对象存到容器中
Properties prop = new Properties();
prop.load(is);
Set<Map.Entry<Object, Object>> entrySet = prop.entrySet();
for (Map.Entry<Object, Object> entry : entrySet) {
String key = entry.getKey().toString();
String beanName = entry.getValue().toString();
Object value = Class.forName(beanName).newInstance();
beans.put(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 4、在使用的时候,直接从工厂拿
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
try {
return beans.get(beanName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(getBean("UserService"));
}
}
?