Spring IOC

经过几天的理解,对IOC有了一些个人理解。
例如我们有一个需求要向mysql数据库中添加一条数据:
1、首先我们要有一个处理插入请求的SqlService类:

public class SqlService {
    private MysqlDal sqlserverdal = new MysqlDal();

    public void add() {
        sqlserverdal.add();
    }

}

2、在SqlService类中 我们需要对数据库进行操作的类MysqlDal :

public class MysqlDal {
    public void add(){
        System.out.println("在mysql数据库中插入了一条数据");
    }
}


为了简化,我们将插入操作只定义为输出一句话“在数据库中插入了一条数据”

3、需要一个测试类来测试:

public class Test {
    public static void main(String args[]) {
        new SqlService().add();
    }
}

运行程序 得到结果
这里写图片描述

从上图可以看到我们完成了预想的结果。
但是,我们突然接到通知说需求变了,原来是向Mysql数据库中插入数据,现在变成了向Oracle数据库中插入数据。 问题来了总得解决,所以我们就想怎么去解决这个问题。数据库变了 原来的MysqlDal类肯定不能用了,那我们就得建立一个向Oracle中插入数据的操作类:

public class OracleDal {
    public void add(){
        System.out.println("在oracle数据库中插入了一条数据");
    }
}

由于数据库的类型变化了,我们在SqlService中的代码也要变化:

public class SqlService {

    private OracleDal oracleDal = new OracleDal();

    public void add() {
        oracleDal.add();
    }

}

改动完后再次运行得到结果:
这里写图片描述

终于通过改动,我们再次完成了需求,但是问题来了,如果今后数据库的类型还要改,是不是我们还得大费周章的修改代码?
显然,这不是一个良好的设计,组件之间高度耦合,可扩展性较差,它违背了DIP原则。高层模块SqlService 类不应该依赖于低层模块OracleDal ,MysqlDal ,两者应该依赖于抽象。那么我们是否可以通过IoC来优化代码呢?答案是肯定的。IOC有2种常见的实现方式:依赖注入和服务定位。其中,依赖注入使用最为广泛。下面我们将深入理解依赖注入(DI),并学会使用。

依赖注入(DI)
在上面的例子中,SqlService 依赖于OracleDal 或MysqlDal对象,并且MysqlDal和OracleDal对象的实例化是在SqlService内部实现的,这种方法并不可取。既然,不能在Order类内部直接绑定依赖关系,那么如何将SqlServerDal对象的引用传递给SqlService 类使用呢。
为了将向数据库中插入数据的操作抽象出来,我们定义一个接口,并且在接口中声明一个add方法:

public interface SqlAdd {
    public void add();
}

我们让数据库操作类实现SqlAdd接口:

public class MysqlDal implements SqlAdd{
    @Override
    public void add() {
        System.out.println("向mysql数据库中插入了一条数据");
    }
}
public class OracleDal implements SqlAdd{
    @Override
    public void add() {
        System.out.println("向Oracle数据库中插入了一条数据");
    }
}

接下来对SqlService进行改造 声明一个SqlAdd接口的对象sqladd,通过调用sqladd的add方法来执行插入操作:

public class SqlService {

    private SqlAdd sqlAdd;
    public void add() {
        sqlAdd.add();
    }

}

到此为止我们对源码的改造只剩下最后一步:对声明的sqladd进行赋值。
赋值的过程就是依赖注入的过程,注入过程有三种:
1、构造函数注入:
我们通过使用SqlService的构造函数对sqlAdd进行注入

public class SqlService {

    private SqlAdd sqlAdd;

    public SqlService(SqlAdd sqlAdd) {
        this.sqlAdd = sqlAdd;
    }

    public void add() {
        sqlAdd.add();
    }

}

在Test中我们传入一个数据库操作对象:

public class Test {
    public static void main(String args[]) {
        new SqlService(new MysqlDal()).add();
    }

}

运行结果:

这里写图片描述

2、属性注入:
我们通过使用SqlService的set方法对sqlAdd进行注入

public class SqlService {

    private SqlAdd sqlAdd;

    public void setSqladd(SqlAdd sqlAdd) {
        this.sqlAdd = sqlAdd;
    }

    public void add() {
        sqlAdd.add();
    }

}

在test中 我们通过sqlservice.setSqladd(new OracleDal());给sqlservice注入

public class Test {
    public static void main(String args[]) {
        SqlService sqlservice = new SqlService();
        sqlservice.setSqladd(new OracleDal());
        sqlservice.add();
    }

}

运行结果如下:
这里写图片描述

IoC容器

前面所有的例子中,我们都是通过手动的方式来创建依赖对象,并将引用传递给被依赖模块。比如:

1 MysqlDal mysqldal = new MysqlDal (); //在外部创建依赖对象
2 new SqlService(new MysqlDal()); //通过构造函数注入依赖

对于大型项目来说,相互依赖的组件比较多。如果还用手动的方式,自己来创建和注入依赖的话,显然效率很低,而且往往还会出现不可控的场面。正因如此,IoC容器诞生了。IoC容器实际上是一个DI框架,它能简化我们的工作量。它包含以下几个功能:

动态创建、注入依赖对象。
管理对象生命周期。
映射依赖关系。

使用Spring进行 依赖注入:

1、传统XML bean标签进行配置
bean.mxl:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="sqlService" class="com.xm.test.SqlService">
        <property name="sqlAdd" ref="mysqlDal" />
    </bean>
    <bean id="mysqlDal" class="com.xm.test.MysqlDal" />
</beans>

Test.java:

package com.xm.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String args[]) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        SqlService sqlservice = ctx.getBean("sqlService", SqlService.class);
        sqlservice.add();
    }

}

2、使用注解的方式进行配置:
使用注解可以减少代码量
bean.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"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
     <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->     
       <context:component-scan base-package="com.xm.test" />
</beans>

Test.java:

package com.xm.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String args[]) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        SqlService sqlservice = ctx.getBean("sqlService", SqlService.class);
        sqlservice.add();
    }

}

MysqlDal.java:

package com.xm.test;

import org.springframework.stereotype.Component;

@Component
public class MysqlDal implements SqlAdd {
    @Override
    public void add() {
        System.out.println("向mysql中插入一条数据");
    }
}

SqlService.java:

package com.xm.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service

public class SqlService {
    @Autowired
    private SqlAdd sqlAdd;

    public void add() {
        sqlAdd.add();
    }

}

总结:Spring容器使我们不需要手动进行依赖注入,而是Spring容器自动调度。更加简化了依赖注入的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值