spring笔记-ioc的理论1 ioc的推理

推理过程

定义接口,获取用户的方法:

package com.lx.dao;

public interface UserDao {

    void getUser();
}

创建UserDaoImpl类实现UserDao的接口,里面能够调用默认获取用户的方法

package com.lx.dao;

public class UserDaoImpl implements UserDao{
    public void getUser() {

        System.out.println("Dao层默认获取用户数据的方法");
        
    }
}

在服务层创建接口,获取用户的方法:

package com.lx.service;

public interface UserService {
    void getUser();
}

在服务层创建UserServiceImpl类实现上接口:

package com.lx.service;

import com.lx.dao.UserDao;


public class UserServiceimpl implements UserService {
  private UserDaoImpl user = new UserDaoImpl();

    public void getUser() {
        System.out.println("在service层调用dao层获取user");
        user.getUser();

    }



}



测试单元:

  @Test
    public void test(){
        UserService user = new UserServiceimpl();
        user.getUser();
    }

测试结果:

在这里插入图片描述
<
在持久层里有一个类(UserDaoImpl),类中有一个是默认获取用户数据的方法(getUser),简称A方法,

想要使用A方法,需要在service层调用dao层的方法,于是在类中(UserServiceImpl)中创建了一个有该方法的dao层对象,通过调用A方法,并将其封装到当前(UserServiceImpl)类中的方法中

在测试单元中,通过创建service层的对象,调用该对象封装好的方法,就可以调用dao层的A方法,用户通过调用service层而无需直接调用dao层,即可使用A方法


如果此时新增一个方法是使用mysql的方法:

package com.lx.dao;

public class UserDaoMysqlimpl implements UserDao{
    public void getUser() {
        System.out.println("Dao层Mysql获取用户数据");

    }
}

虽然方法名相同,但是实现需要修改业务层的代码,

    private UserDao userDao = new UserDaoMysqlimpl();

    public void getUser() {
        System.out.println("在service层调用dao层获取user");
        userDao.getUser();

    }

在这里插入图片描述

在这里理解,都是获取用户的方法,但只是方式不同,使用不同的方式却需要修改大量的…代码

像一个办法,将主动权交给用户,而不是业务层

再新增一个Oracle方式获取user的方法

package com.lx.dao;

public class UserDaoOrcleimpl implements UserDao{
    public void getUser() {
        System.out.println("Dao层获取用户orcle的方法");
    }
}

在业务层,通过set可以实现动态的注入

package com.lx.service;

import com.lx.dao.UserDao;
import com.lx.dao.UserDaoImpl;
import com.lx.dao.UserDaoMysqlimpl;

public class UserServiceimpl implements UserService {

    private UserDao userDao ;

    //利用set进行动态实现值的注入!
    public void setUserDao(UserDao userDao) {

        this.userDao = userDao;

    }

    public void getUser() {
        System.out.println("在service层调用dao层获取user");
        userDao.getUser();

    }

}

这样就可以利用set注入的方式,将主动权给了用户,用户想用什么样的方式就创建什么样的对象,通过set方法调用合适的方法

测试单元:

@Test
    public void test2(){
        UserServiceimpl userServiceimpl = new UserServiceimpl();
        userServiceimpl.setUserDao(new UserDaoImpl());
        userServiceimpl.getUser();

        System.out.println("=============");

        userServiceimpl.setUserDao(new UserDaoMysqlimpl());
        userServiceimpl.getUser();

        System.out.println("==============");

        userServiceimpl.setUserDao(new UserDaoOrcleimpl());
        userServiceimpl.getUser();
    }

在这里插入图片描述

  • 以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了它只负责提供一个接口 .
  • 这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 .这也就是IOC的原型 !



IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认
为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系

完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为
所谓控制反转就是:获得依赖对象的方式反转了。

在这里插入图片描述
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,
新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用
时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为
一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现
控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

Hello Spring

先理解ioc的本质,创建第一个spring

创建一个Hello实体类:

里面有属性str
str的get set方法
toStrng方法 helloWord方法

package com.lx.pojo;

public class Hello {

    private String str;


    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }



    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }

    public void helloWord() {
        System.out.println("Hello Spring ! hello Word !");
    }
}

resource目录下创建beans.xml配置文件
在这里插入图片描述在这里插入图片描述

配置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/beans/spring-beans.xsd">

    <!--使用Spring来创建对象,在Spring这些都称为Bean

类型 变量名  = new 类型();
Hello hello = new Hello();

id = 变量名
class = new 的对象;
property 相当于给对象中的属性设置一个值!
-->
    <bean id="hello" class="com.lx.pojo.Hello">
        <property name="str" value="Hello Spring"/>
    </bean>
</beans>

测试类:

import com.lx.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //我们的对象现在都在Spring中的管理了,我们要使用,直接去里面取出来就可以!
//        Hello hello = (Hello) context.getBean("hello");
        Hello hello =  context.getBean("hello",Hello.class);
        System.out.println(hello.toString());
        hello.helloWord();
    }
}

测试结果:
在这里插入图片描述

配置分析:
bean就是java对象 , 由Spring创建和管理

id = 变量名
class = new 的对象;
property 相当于给对象中的属性设置一个值!
ref : 引用Spring容器中创建好的对象

而在上述例子中的hello对象:
【 hello 对象是由Spring创建的 】
【hello 对象的属性是由Spring容器设置的 】

!!! 对象的属性通过propetry赋值时,必须要有该属性的set get方法

在spring中新增一个小例子 nohello

<?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/beans/spring-beans.xsd">

    <!--使用Spring来创建对象,在Spring这些都称为Bean

类型 变量名  = new 类型();
Hello hello = new Hello();

id = 变量名
class = new 的对象;
property 相当于给对象中的属性设置一个值!
-->
    <bean id="hello" class="com.lx.pojo.Hello">
        <property name="str" value="Hello Spring"/>
    </bean>

    <bean id="nohello" class="com.lx.pojo.Hello">
        <property name="str" value="fuck Spring"/>
    </bean>
</beans>

通过id = nohello 创建一个新的对象

import com.lx.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //我们的对象现在都在Spring中的管理了,我们要使用,直接去里面取出来就可以!
//        Hello hello = (Hello) context.getBean("hello");
        Hello hello =  context.getBean("hello",Hello.class);
        System.out.println(hello.toString());
        hello.helloWord();

        System.out.println("====================");

        Hello nohello = context.getBean("nohello", Hello.class);
        System.out.println(nohello.toString());
        nohello.helloWord();
    }
}


在这里插入图片描述
创建了两个对象

这个过程就叫控制反转 :

控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的

反转 : 程序本身不创建对象 , 而变成被动的接收对象 .

依赖注入 : 就是利用set方法来进行注入的.

IOC是一种编程思想,由主动的编程变成被动的接收

可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .


接下来对最初的案例进行一下修改:

<?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/beans/spring-beans.xsd">

    <bean id="mysqlImpl" class="com.lx.dao.UserDaoMysqlimpl"/>
    <bean id="orcleImpl" class="com.lx.dao.UserDaoOrcleimpl" />
    <bean id="userImpl" class="com.lx.dao.UserDaoImpl"/>

    <bean id="mysql" class="com.lx.service.UserServiceimpl">
        <property name="userDao" ref="mysqlImpl" />
    </bean>

    <bean id="orcle" class="com.lx.service.UserServiceimpl">
        <property name="userDao" ref="orcleImpl"/>
    </bean>

    <bean id="moren" class="com.lx.service.UserServiceimpl">
        <property name="userDao" ref="userImpl"/>
    </bean>



    <!--
  ref : 引用Spring容器中创建好的对象
  value : 具体的值,基本数据类型!
    -->
</beans>
    @Test
    public void test3(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserServiceimpl moren = context.getBean("moren", UserServiceimpl.class);
        moren.getUser();
        System.out.println("-----------------");

        UserServiceimpl mysql = context.getBean("mysql", UserServiceimpl.class);
        mysql.getUser();
        System.out.println("------------");

        UserDaoMysqlimpl mysqlImpl = context.getBean("mysqlImpl", UserDaoMysqlimpl.class);
        mysqlImpl.getUser();
    }

在这里插入图片描述

设置的6个bean里,其中前三个,可以让用户直接创建dao层的对象,
后三个,依然是先创建了service层的对象,在service使用set注入的方式,将在spring配置好的引用的对象注入进去,这样用户可以不用直接创建dao层的对象也能实现


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值