Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!

IOC理论推导

该模块涉及Spring中的set注入,IOC原型,实现控制反转,希望大家能够认真的理解!

一、常规的开发架构


1、编写Dao接口

public interface UserDao {
    //定义接口方法,获取用户数据
    void getUser();
}

2、编写接口实现类继承Dao接口

public class UserDaoImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("获取用户数据!");
    }
}

3、编写service接口

public interface UserService {
    void getUser();
}

4、编写service实现类

public class UserServiceImpl implements UserService{
  //想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
   private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

5、测试

public class MyTest {
    public static void main(String[] args) {
        //创建业务层对象
        UserServiceImpl service = new UserServiceImpl();
        
        //调用业务层方法
        service.getUser();
    }
}

6、执行结果

7、新需求,如果我们想要在Dao层多加一个需求,需要怎么实现调用呢?
新需求:

public class UserDaoMysqlImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("通过Mysql方法,获取用户数据!");
    }
}

8、在service实现类中创建UserDaoMysqlImpl对象

public class UserServiceImpl implements UserService{
  //想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
   private UserDao userDao = new UserDaoMysqlImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

9、测试

public class MyTest {
    public static void main(String[] args) {
        //创建业务层对象
        UserServiceImpl service = new UserServiceImpl();

        //调用业务层方法
        service.getUser();
    }
}

10、执行结果

我们不难发现,service实现类中要重新创建DaoImpl对象,新需求的出现会改变原来代码的功能,耦合性极高!假设我们这样的需求成千上万,这种方式根本就无法实现,每次变动都需要改动大量的代码,牵一发而动全身!!!

二、新的开发理念


1、新需求中会有多个Dao的实现类

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第1张图片

2、在service的实现类中使用set注入

public class UserServiceImpl implements UserService {
    //想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
    //这里直接创建接口的对象,便于调用接口实现类的方法(多态)
    private UserDao userDao;

    /* set注入:运用多态的理念,当有多个Dao实现类的时候,我们在Servlet中创建UserServiceImpl对象,
        直接调用这个setUserDao,动态传入需要用到的实现类对象
        就可以实现动态调用不同的Dao实现类*/
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

3、测试中如果我们想要调用其他的Dao实现类方法,可以这样调用

public class MyTest {
    public static void main(String[] args) {
        //创建业务层对象
        UserServiceImpl service = new UserServiceImpl();

        //调用set方法,将需要用到的实现类传进去,就可以实现不改动代态调用码,动
        service.setUserDao(new UserDaoOracleImpl());
        //调用业务层方法
        service.getUser();
    }
}

4、执行结果

总结二者的区别:
之前,在service实现类中,程序都是主动创建对象,控制权在程序员手上!
而现在我们使用了set注入,程序不在具有主动性,而是被动的接收对象!
仔细思考一下,之前所有的东西都是由程序进行控制创建,而现在是由我们自行控制创建对象,把主动权交给了调用者,程序不用再去管怎么创建,怎么实现,而是更多的关注业务的实现,它只负责提供一个set接口,这样耦合性大大的被降低了,这也就是我们的IOC原型理念!

三、案例完全按照IOC进行配置优化


1、配置Beans.xml文件(详情见代码中的注释)



    

    
    
    

        
    

2、测试

public class MyTest {
    public static void main(String[] args) {
        //获取Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //容器获取到,需要哪个对象直接通过getBean获取即可
        UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("serviceImpl");
        
        //我们在配置文件中已经给serviceImpl的userdao属性注入了mysqlImpl对象,这里直接调用getUser方法即可
        serviceImpl.getUser();
    }
}

3、控制台打印结果

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第2张图片

可见,通过由Spring容器统一对对象进行创建、管理和装配,使得调用者不需要去代码中修改,只在配置文件中按照需求修改即可,而我们的程序只需要被动的接收我们配置好的对象就可以,简单方便!!!!!!

HelloSpring

带你使用IOC容器编写第一个HelloSpring代码!

一、创建实体类

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 + '\'' +
                '}';
    }
}

二、去Bean.xml文件配置实体类



    
    
    
    

    

三、测试

public class MyTest {
    public static void main(String[] args) {
        /*获取Application的上下文对象!!!
         *
         * */
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        /*获取对象的方法
         * 由于我们已经将这个实体类在Bean.xml文件中配置,所以不需要再new对象
         * 直接通过Application的上下文对象调用getBean方法就能获得实体类对象
         * 里面传的参数是Bean.xml配置文件中实体类的id*/
        Hello hello = (Hello) context.getBean("hello");

        //测试调用实体类中的方法
        System.out.println(hello.toString());
    }
}

四、控制台结果

IOC控制反转

结合我们第一个HelloSpring程序,这个过程就叫做控制反转
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的



    
    
    
    

    

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

public class MyTest {
    public static void main(String[] args) {
        /*获取Application的上下文对象!!!
         *也就是获取Spring容器
         * */
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        /*获取对象的方法
         * 由于我们已经将这个实体类在Bean.xml文件中配置,所以不需要再new对象
         * 直接通过Application的上下文对象调用getBean方法就能获得实体类对象
         * 里面传的参数是Bean.xml配置文件中实体类的id*/
        Hello hello = (Hello) context.getBean("hello");

        //测试调用实体类中的方法
        System.out.println(hello.toString());
    }
}

依赖注入:就是利用set方法进行注入
只有实体类中写了set方法,我们才能在Bean,xml配置文件中对实体类的属性进行修改

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第3张图片

测试:
1、将实体类中的set方法删掉

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第4张图片

2、bean.xml中的属性名爆红,意味着无法进行相关的操作

IOC是一种编程思想,由主动的编程变成被动的接收,由对象由Spring来创建、管理和装配!!!!!!

IOC创建对象的方式

一、IOC默认使用实体类的无参构造进行对象的创建
1、定义一个实体类

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第5张图片

2、在bean.xml配置文件配置实体类

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第6张图片

3、测试Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第7张图片

4、控制台结果

二、如何用有参构造进行创建对象呢?
准备工作:
先在实体类中增加一个带参构造(声明了带参构造那么默认的无参构造就消失了),并且定义一个方法

Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第8张图片

1、通过实体类的属性下标index进行创建和赋值
按照属性的顺序从0开始,进行赋值





    
       
    

2、通过属性的类型进行赋值(有局限性,如果我的实体类中有多个相同类型的属性,那么就无法识别了)


    
       
    

控制台结果:Spring篇——带你推导、理解和使用Spring中的IOC,一篇文章搞定!_第9张图片

3、可以直接通过参数名对属性进行赋值


    
       
    

控制台打印结果:

总结:在配置文件加载的时候,容器中管理的对象就已经被初始化了!!!

至此,你对IOC的概念、他究竟如何实现控制反转以及实现的方法已经掌握,后续会持续更新关于Spring的技术讲解,敬请期待!

你可能感兴趣的:(Spring,spring,java,后端)