初识IOC

1. 概述

控制反转(Inverse Of Control不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。

控制:在java中指的是对象的控制权限(创建、销毁)

反转:指的是对象控制权由原来 由开发者在类中手动控制 反转到  Spring容器控制

举例说明:

  • 传统方式

之前我们需要一个userDao实例,需要开发者自己手动创建 new UserDao();

  • IOC方式

现在我们需要一个userDao实例,直接从springIOC容器获得,对象的创建权交给了spring控制

2. 自定义IOC容器

2.1 介绍

需求

实现service层与dao层代码解耦合

步骤分析

  1. 创建java项目,导入自定义IOC相关坐标
  2. 编写Dao接口和实现类
  3. 编写Service接口和实现类
  4. 编写测试代码

2.2 实现

      1)创建java项目,导入自定义IOC相关坐标

<dependencies>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>


    </dependencies>

     2)编写Dao接口和实现类

package com.lagou.dao;

public interface IUserDao {

    public void save();

}
package com.lagou.dao.impl;

import com.lagou.dao.IUserDao;

public class UserDaoImpl implements IUserDao {

    public void save() {
        System.out.println("dao被调用了,保存成功...");
    }
}

         3)编写Service接口和实现类

package com.lagou.service;

public interface IUserService {

    public void save() throws ClassNotFoundException, IllegalAccessException, InstantiationException;


}
package com.lagou.service.impl;

import com.lagou.dao.IUserDao;
import com.lagou.service.IUserService;
import com.lagou.utils.BeanFactory;

public class UserServiceImpl implements IUserService {


    public void save() {
        // 调用dao层方法 传统方式 :存在编译期依赖:耦合重
        IUserDao userDao = new UserDaoImpl();
        userDao.save();

    }

}

           4)编写测试代码

package com.lagou.test;

import com.lagou.service.IUserService;
import com.lagou.service.impl.UserServiceImpl;
import org.junit.Test;

public class SpringTest {

    @Test
    public void test1() {

        // 获取业务层对象
        IUserService userService = new UserServiceImpl();

        // 调用save方法
        userService.save();


    }



}

          5)问题

当前service对象和dao对象耦合度太高,而且每次new的都是一个新的对象,导致服务器压力过大。

解耦合的原则是编译期不依赖,而运行期依赖就行了。

         6)编写beans.xml

把所有需要创建对象的信息定义在配置文件中。

<beans>

<!--id:标识    class:存的就是要生成实例的类的全路径-->
    <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean>



</beans>

        7)编写BeanFactory工具类

package com.lagou.utils;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanFactory {


    private static Map<String,Object> iocmap = new HashMap<>();

    // 程序启动时,初始化对象实例
    static {

        //1.读取配置文件
        InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");

        //2.解析xml(dom4j)
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
         //3.编写xpath表达式
            String xpath = "//bean";

         //4.获取到所有的bean标签
            List<Element> list = document.selectNodes(xpath);

         //5.遍历并使用反射创建对象实例,存到map集合(ioc容器)中
            for (Element element : list) {
                String id = element.attributeValue("id");
                //className : com.lagou.dao.impl.UserDaoImpl
                String className = element.attributeValue("class");
                //使用反射生成实例对象
                Object o = Class.forName(className).newInstance();
                // 存到map中 key:id value:o
                iocmap.put(id,o);
            }




        } catch (DocumentException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }


        public static Object getBean(String beanId){
            Object o = iocmap.get(beanId);
            return o;
        }


}

        8)修改UserServiceImpl实现类

package com.lagou.service.impl;

import com.lagou.dao.IUserDao;
import com.lagou.service.IUserService;
import com.lagou.utils.BeanFactory;

public class UserServiceImpl implements IUserService {


    public void save() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        // 调用dao层方法 传统方式 :存在编译期依赖:耦合重
        //IUserDao userDao = new UserDaoImpl();

        //反射
        // IUserDao userDao = (IUserDao) Class.forName("com.lagou.dao.impl.UserDaoImpl").newInstance();

        IUserDao userDao = (IUserDao) BeanFactory.getBean("userDao");
        userDao.save();

    }

}

 

3. 知识小结

  • 其实升级后的BeanFactory就是一个简单的SpringIOC容器所具备的功能。

 

  • 之前我们需要一个userDao实例,需要开发者自己手动创建 new UserDao();

 

  • 现在我们需要一个userdao实例,直接从springIOC容器获得,对象的创建权交给了spring控制

 

  • 最终目标:代码解耦合

 

节选自拉钩教育JAVA系列教程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值