耦合:耦合指的就是对象之间的依赖关系。对象之间的耦合越高,维护成本越高。
案例:没有引入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对象使用配置文件配置起来
当服务器启动时读取配置文件
把这些对象通过反射创建出来并保存在容器中
在使用的时候,直接从工厂拿
IOC (Inverse of Control)即控制反转:由ioc容器来创建依赖对象,程序只需要从IOC容器获取创建好的对象。
原来:
我们在获取对象时,都是采用new的方式。是主动的。
?
?
现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
?这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
案例一
/**
* 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
?
package com.zhy.factory;
import com.zhy.factory.Service.UserService;
import java.io.InputStream;
import java.util.Properties;
//问题:1.每次都会创建新的对象 2.获得对象时才读取配置文件
public class Bean_Factory_v2 {
public static Object getBean(String beanName) {
//*************1.读取配置文件beans.properties*****************
//不能使用项目发布后没有src目录
// InputStream InputStream = new FileInputStream("src\\main\\resources\\beans.properties");
//ClassLoader的作用:负责加载classes目录下的资源
try {
InputStream inputStream = Bean_Factory_v2.class.getClassLoader().getResourceAsStream("beans.properties");
//properties继承了HashTab,作用是加载*.properties的配置文件
Properties properties = new Properties();
properties.load(inputStream);
//*************2.根据配置文件中的value值创建(使用反射)对象*****************
return Class.forName(properties.getProperty(beanName)).newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args){
UserService userService = (UserService) Bean_Factory_v2.getBean("userService");
userService.addUser();
}
}
业务层?
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = (UserDao) BeanFactory.getBean("UserDao");
public void addUser(){
userDao.addUser();
}
}
测试:
public class Client {
//模拟servlet
public static void main(String[] args) {
UserService userService= (UserService) Bean_Factory_v2.getBean("userService");
userService.addUser();
for (int i = 0; i < 5; i++) {
UserService userServicei= (UserService) Bean_Factory_v2.getBean("userService");
System.out.println(userServicei);
}
}
}
结果:
问题:
每次都会创建新的对象
程序运行时才创建对象(读取配置文件)
?案例三
package com.zhy.factory;
import com.zhy.factory.Service.UserService;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Bean_Factory_v3 {
public static Map<String,Object>iocMap= new HashMap<String,Object>();
static {
try {
//解决:2.获得对象时才读取配置文件
InputStream inputStream = Bean_Factory_v2.class.getClassLoader().getResourceAsStream("beans.properties");
Properties properties = new Properties();
properties.load(inputStream);
//解决:每次都会创建新的对象,在静态代码块中创建对象,并装到Map集合中,每次调用对象直接从Map集合中取,无序在多次创建对象了
Set<Object> keySet = properties.keySet();
for (Object key :keySet) {
String propertiesValues = properties.getProperty((String) key);
iocMap.put((String)key ,Class.forName(propertiesValues).newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getBean(String beanName) {
return iocMap.get(beanName);
}
public static void main(String[] args){
UserService userService = (UserService) Bean_Factory_v3.getBean("userService");
userService.addUser();
}
}
业务层
package com.zhy.factory.Service;
import com.zhy.dao.UserDao;
import com.zhy.factory.Bean_Factory_v3;
public class UserServiceImpl implements UserService{
// private UserDao userDao=new UserDaoImpl();
//调用工厂Bean_Factory_v1中的方法生成一个userDao解决程序的高耦合
// private UserDao userDao= Bean_Factory_v1.getUserDaoImpl();
// private UserDao userDao= (UserDao) Bean_Factory_v2.getBean("userDao");
private UserDao userDao= (UserDao) Bean_Factory_v3.getBean("userDao");
@Override
public void addUser(){
userDao.addUser();
}
}
测试:
package com.zhy.Servlet;
import com.zhy.factory.Service.UserService;
import com.zhy.factory.Bean_Factory_v3;
public class Client {
//模拟servlet
public static void main(String[] args) {
//高耦合:硬编码
// UserService userService = new UserServiceImpl();
//调用工厂Bean_Factory_v1中的方法来解决程序的高耦合
// UserService userService=Bean_Factory_v1.getUserService();
// UserService userService= (UserService) Bean_Factory_v2.getBean("userService");
UserService userService= (UserService) Bean_Factory_v3.getBean("userService");
userService.addUser();
for (int i = 0; i < 5; i++) {
UserService userServicei= (UserService) Bean_Factory_v3.getBean("userService");
System.out.println(userServicei);
}
}
}
结果:
?