Spring的工程模式的IOC解决程序耦合

1.1、什么是IOC

          IOC (Inverse of Control)即控制反转:正传是自己创建依赖对象;反正是有IOC工厂来创建依赖对象;

        原来:

              我们在获取对象时,都是采用new的方式。是主动的。

        现在:

              我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。

1.2、程序的耦合

  • 耦合:耦合指的就是对象之间的依赖关系。对象之间的耦合越高,维护成本越高。

  • 案例:没有引入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(工厂模式)解耦:

    1. 把所有的dao和service对象使用配置文件配置起来

    2. 当服务器启动时读取配置文件

    3. 把这些对象通过反射创建出来并保存在容器中

    4. 在使用的时候,直接从工厂拿

 1.3、工厂模式的IOC解耦

案例一:

/**
 * 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、配置文件xx.properties配置要使用的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);
        }
    }
}

结果:

  • 问题:

    1. 每次都会创建新的对象

    2. 程序运行时才创建对象(读取配置文件)

 案例三:

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"));
    }
}

  • 16
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值