Sring-IOC控制反转(详解)

Sring IOC

介绍

控制反转(inverse of control) 这个不是什么技术,而是指的一种思想。它的目的是直到我们设计出更加松耦合的程序。

控制:在java中指的是对象的控制权限(创建、销毁)
反转:指的是对象控制权由原来 由开发者在类中手动控制 反转到由Spring容器控制
一句大白话:bean的创建和销毁交给spring容器管理

IOC大概的原理

pom.xml:

<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>

myBean.xml:

<beans>
    <bean id="orderDao" class="com.llz.dao.impl.OrderDaoImpl"/>
    <bean id="orderService" class="com.llz.service.impl.OrderServiceImpl"/>
</beans>

工厂类:

public class MyBeanFactory {
    private static Map<String,Object> map = new HashMap<String, Object>();
    static{
        try {
            //加载myBean.xml,解析xml,将所有的配置的内容放入到map中
            //使用dom4j和xpath技术,导入这两个jar包
            InputStream is = MyBeanFactory.class.getClassLoader().getResourceAsStream("myBean.xml");
            Document doc = new SAXReader().read(is);
            List<Element> list = doc.selectNodes("//bean");
            for (Element element : list) {
                //获取id和class属性
                String id = element.attributeValue("id");
                String classValue = element.attributeValue("class");
                //使用全限定类名创建实现类对象
                Object obj = Class.forName(classValue).newInstance();
                //将id作为key 对象作为value放入map中
                map.put(id,obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Object getBean(String id){
        return map.get(id);
    }
}

service类:

public class OrderServiceImpl implements OrderService {
    //private OrderDao orderDao = new OrderDaoImpl();
    //若orderDao的实现类发生了改变,重新编写了OrderDaoImpl2类,导致service代码的改变
    //private OrderDao orderDao = new OrderDaoImpl2();
    //这里我们直接使用工厂模式替代
    private OrderDao orderDao = (OrderDao) MyBeanFactory.getBean("orderDao");
    public void save() {
        System.out.println("orderServiceImpl 执行保存操作");
        orderDao.save();
    }
}

如上:即是springIOC的大致操作,它底层用工厂代替我们对对象进行创建和销毁。

1.Spring的IOC入门(xml方式)

需求
  使用spring的ioc实现UserDao层保存操作
步骤分析及代码实现

  1. 导入依赖(spring-context)
  2. 编写UserDao接口及其实现类
  3. 编写一个spring的配置文件(名字任意):applicationContext.xml
    • 通过bean标签配置dao
  4. 编写测试代码
    • 获取spring容器(工厂)对象
    • 通过工厂对象获取dao的对象
    • 调用save方法

pom.xml

<!--导入spring的ioc核心依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

在这里插入图片描述
spring的核心配置文件,名字applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/applicationContext/spring-beans.xsd">
    <bean id="userDao" class="com.llz.dao.impl.UserDaoImpl"/>
</beans>

测试类

public class TestHelloIOC {
    @Test
    public void testIocHello(){
        //- 获取spring容器(工厂)对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //- 通过工厂对象获取dao的对象
        UserDao userDao = (UserDao) context.getBean("userDao");
        //- 调用save方法
        userDao.save();
    }
}

Spring相关API

Spring的API体系异常庞大,现在只关注两个BeanFactory和ApplicationContext

  • 进入BeanFactory之后,点击ctrl+h打开体系结构图

在这里插入图片描述
实现类:

* FileSystemXmlApplicationContext【了解】
功能:从指定磁盘目录加载xml配置文件,创建spring的ioc容器
* ClassPathXmlApplicationContext
功能:从类路径下加载xml配置文件,创建spring的ioc容器
* AnnotationConfigApplicationContext
功能:加载注解配置类,创建spring的ioc容器

运行时常见异常
在这里插入图片描述

applicationContext.xml配置文件

<!--
        bean:将配置的对象加入spring容器管理
            id属性(name属性):给bean起个名字,要保证当前项目中唯一
            class属性:配置对象对应的全限定类名(类且有无参构造器)

            其他的配置:
            scope属性:配置对象的作用范围(单实例还是多实例等)
                常见俩值:
                    singleton:默认值,单实例对象
                    prototype:多实例对象,一般用不上,struts2框架中action是多实例
            init-method属性:指定对象创建成功之后要执行的方法(初始化操作),我们一般用不上,框架底层使用
            destroy-method属性:指定对象销毁之前要执行的方法(销毁操作),我们一般用不上,框架底层使用

    -->
<bean id="userDao" class="com.llz.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="dest"/>

2.Spring-IOC入门(注解方式)

Spring常用注解主要是替代<bean> 的配置

<bean id="名字" class="类的全限定类名" scope="" init-method="" destory-method="">
	<property name="属性名" value|ref=""/>
</bean>

spring中ioc的注解要想使用,需要先开启组件扫描

<context:component-scan base-package="com.llz"/>

使用在类上的注解

@Component:组件

  • 替代bean标签,将类的产生的对象加入到spring容器中
  • value属性:设置在spring容器中的名字.也可以不写名字,名字的默认值就是类名首字母小写
  • 在开发中经常使用的时候它的三个衍生的注解(可以当成孩子)
    @Controller:在web层的类上 (重要)
    @Service:在service层的类上 (重要)
    @Repository:在dao层的类上 (重要)
    三个衍生的注解目前和Component一样,几乎没有区别,但是建议根据类的位置使用不同的注解
    在这里插入图片描述
    @Scope:作用域
    在这里插入图片描述

使用在成员变量上的注解-注入

可以不给成员变量提供set方法.也可以提供set方法
注解可以作用在成员变量上,也可以作用在set方法上.
@Value
在这里插入图片描述
@Autowired

  • 给引用类型的成员变量进行赋值.值是已经存在于spring容器中,相当于ref属性
  • 默认是按照数据类型注入.
    • 若只找到一个此类型的对象,直接注入
    • 若找到了多个此类型的对象,把变量名作为名字去spring容器中匹配.若匹配到了直接注入;若匹配不到就会报异常
    • 可以搭配使用 @Qualifier 注解,使用它的value属性指定名字进行注入(装配)
      在这里插入图片描述
      扩展:jdk也提供了一个注解 @Resource,做的事情和@Autowired及@Qualifier的作用是一样的
      在这里插入图片描述

总结

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值