spring——(1)ioc容器和Di依赖注入

今天开始spring的系列文章,由于我也是边学边写,如果有不对的地方还请指出来,大家一起学习共同进步。
在进行Spring的第一篇讲解前首先搭建一下环境,这里有一个链接供大家参考:http://www.yiibai.com/spring/spring-tutorial-for-beginners.html。在写这篇文章之前我看了很多视频和博客,他们首先会将一大堆理论,我看的是云里雾里,其实我感觉在学习一个东西之前没有必要对理论的东西有过多的研究,直接看例子然后自己打代码,慢慢的自己就明白了,关于ioc容器和Di注入网上有很多理论的讲解,想看的直接百度就行了,下面我直接上例子:
首先看一下我的项目结构:
这里写图片描述

创建接口OneInterface:

public interface OneInterface {

    public void say(String arg);

}

创建类OneInterfaceImpl继承接口并实现接口方法:

public class OneInterfaceImpl implements OneInterface {

    public void say(String arg) {
        System.out.println("ServiceImpl say: " + arg);
    }

}

现在如果我们想使用OneInterfaceImpl,需要这样做:

    public static void main(String[] args) {
        OneInterface oneInterface=new OneInterfaceImpl();
        oneInterface.say("hello");
    }

现在我们使用ioc容器来看看:
首先创建一个配置文件spring-ioc.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">

    <bean id="oneInterface" class="com.mss.test.OneInterfaceImpl"></bean>
</beans>

除了一些必要的声明之外,我在里面加了OneInterfaceImpl这个类的声明,id是这个类的标识(配置文件中的id必须是唯一的),class是这个类的位置。
下面直接就可以获取OneInterfaceImpl的实例,而不需要New一个对象。

    public static void main(String[] args) {
         ApplicationContext context =
                    new ClassPathXmlApplicationContext("spring-ioc.xml");
         OneInterface oneInterface=(OneInterface) context.getBean("oneInterface");
         oneInterface.say("hello");
    }

这就是ioc容器,将需要的类配置到文件中,我们直接就可以获取这个类的实例。

为了以后方便测试,这里我们使用junit做一次,以后都会使用junit做测试,不懂的先去百度一下。
现在我们创建一个junit单元测试的基类:

public class UnitTestBase {

    private ClassPathXmlApplicationContext context;

    private String springXmlpath;

    public UnitTestBase() {}

    public UnitTestBase(String springXmlpath) {
        this.springXmlpath = springXmlpath;
    }

    //测试之前执行,在这里是加载配置文件
    @Before
    public void before() {
        if (StringUtils.isEmpty(springXmlpath)) {
            springXmlpath = "classpath*:spring-*.xml";
        }
        try {
            context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
            context.start();
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    //测试完成之后执行
    @After
    public void after() {
        context.destroy();
    }

    @SuppressWarnings("unchecked")
    protected <T extends Object> T getBean(String beanId) {
        try {
            return (T)context.getBean(beanId);
        } catch (BeansException e) {
            e.printStackTrace();
            return null;
        }
    }

    protected <T extends Object> T getBean(Class<T> clazz) {
        try {
            return context.getBean(clazz);
        } catch (BeansException e) {
            e.printStackTrace();
            return null;
        }
    }

}

接着创建一个测试类TestOneInterface:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase{

    public TestOneInterface() {
        super("classpath*:spring-ioc.xml");
    }


    @Test
    public void test() {
        OneInterface oneInterface=super.getBean("oneInterface");
//      OneInterface oneInterface=super.getBean(OneInterfaceImpl.class);
        oneInterface.say("hello");
    }

}

这样我们之间运行test这个方法就完成了和前面一样的操作。

ioc容器就先讲这么多,下面讲一下Di依赖注入。
一个类中会有一个或多个参数,我们前面通过ioc获取了类的实例,但是如果想在获取到这个实例之前就给这个类的一个或多个参数设置初始值该怎么办呢?这就用到Di依赖注入了。我们来看一个例子:
这个例子是模拟在service里处理业务逻辑,然后保存数据到DAO中。
首先是保存数据的接口和实现类:

public interface InjectionDAO {

    public void save(String arg);

}
public class InjectionDAOImpl implements InjectionDAO{

    public void save(String arg) {
        // TODO Auto-generated method stub
        System.out.println("向数据库保存数据"+arg);
    }

}

然后是处理业务逻辑的接口和类:

public interface InjectionService {

    public void save(String arg);

}
public class InjectionServiceImpl implements InjectionService {

    InjectionDAO injectionDAO;

    public void setInjectionDAO(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }

    public void save(String arg) {
        // TODO Auto-generated method stub
        System.out.println("处理数据"+arg);
        arg=arg+":已处理";
        injectionDAO.save(arg);
    }

}

在InjectionServiceImpl 中有一个InjectionDAO的参数,我们就在获取InjectionServiceImpl的实例之前给InjectionDAO初始化(注意:要给参数设置set方法),修改配置文件spring-ioc.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">

    <bean id="oneInterface" class="com.mss.test.OneInterfaceImpl"></bean>

    <bean id="injectionService" class="com.mss.test.InjectionServiceImpl">
        <property name="injectionDAO" ref="injectionDAO"></property>
    </bean>

    <bean id="injectionDAO" class="com.mss.test.InjectionDAOImpl"></bean>
</beans>

我们在配置InjectionServiceImpl时添加了一个属性:

<property name="injectionDAO" ref="injectionDAO"></property>

这里的name就是参数名,注意这里的参数名要和InjectionServiceImpl中定义的一样;ref对应的是值,也就是Id=injectionDAO的bean。这样我们在获取InjectionServiceImpl的实例时就会自动将injectionDAO的实例赋值给他。
下面我们测试一下:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase{

    public TestOneInterface() {
        super("classpath*:spring-ioc.xml");
    }


    @Test
    public void test() {
        OneInterface oneInterface=super.getBean("oneInterface");
//      OneInterface oneInterface=super.getBean(OneInterfaceImpl.class);
        oneInterface.say("hello");
    }

    @Test
    public void testInjection() {
        InjectionService injectionService=super.getBean("injectionService");
        injectionService.save("hello");
    }

}

运行testInjection() 这个方法,运行结果如下:

处理数据hello
向数据库保存数据:hello:已处理

前面我们是通过set方法注入,我们也可以通过构造函数注入,修改配置文件spring-ioc.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">

    <bean id="oneInterface" class="com.mss.test.OneInterfaceImpl"></bean>


    <bean id="injectionService" class="com.mss.test.InjectionServiceImpl">
        <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
    </bean>

    <bean id="injectionDAO" class="com.mss.test.InjectionDAOImpl"></bean>
</beans>

这里我们把InjectionServiceImpl里的属性改为:

<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>

其实和之前是一样的,只是修改了属性名,由于是构造函数注入,我们要给类添加一个构造函数:

public class InjectionServiceImpl implements InjectionService {

    InjectionDAO injectionDAO;

    public InjectionServiceImpl(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }

    public void setInjectionDAO(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }

    public void save(String arg) {
        // TODO Auto-generated method stub
        System.out.println("处理数据"+arg);
        arg=arg+":已处理";
        injectionDAO.save(arg);
    }

}

运行之后结果是一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
控制反转(Inversion of Control,IoC)和依赖注入(Dependency Injection,DI)是面向对象编程中的两个重要概念。它们可以帮助我们更好地实现代码的松耦合,提高代码的可维护性和可扩展性。 IoC是一种编程思想,它将程序的控制权从程序员手中转移到了IoC容器中,由IoC容器来管理和调用对象之间的依赖关系。IoC容器就像是一个工厂,它负责创建和管理对象,程序员只需要告诉IoC容器需要哪些对象,IoC容器就会根据配置文件或者注解等方式来创建对象,并将它们组合起来。 DIIoC的一种具体实现方式,它通过构造函数、属性或者方法等方式将依赖关系注入到对象中。当一个对象需要另一个对象时,它不会直接创建这个对象,而是通过IoC容器来获取这个对象。通过DI,我们可以实现对象之间的松耦合,提高代码的可维护性和可测试性。 下面是一个简单的例子,演示如何使用IoC容器DI实现对象之间的依赖注入: ```java // 定义接口 public interface MessageService { void send(String message); } // 实现接口 public class EmailService implements MessageService { public void send(String message) { System.out.println("Email sent: " + message); } } // 定义需要依赖注入的类 public class MyClass { private MessageService messageService; // 通过构造函数注入依赖 public MyClass(MessageService messageService) { this.messageService = messageService; } public void doSomething() { // 使用依赖的方法 messageService.send("Hello World!"); } } // 使用IoC容器创建对象并注入依赖 public class Main { public static void main(String[] args) { // 创建IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从IoC容器中获取对象 MyClass myClass = (MyClass) context.getBean("myClass"); // 调用方法 myClass.doSomething(); } } ``` 在上面的例子中,我们定义了一个MessageService接口和一个EmailService实现类。然后我们定义了一个MyClass类,它需要依赖MessageService对象来完成一些操作。通过构造函数注入依赖,我们可以将MessageService对象注入到MyClass中。最后,在使用IoC容器创建对象时,我们可以通过配置文件或者注解等方式来指定依赖的实现类,IoC容器会自动创建对象并注入依赖。 总之,IoCDI是非常重要的编程思想,它们可以帮助我们更好地管理对象之间的依赖关系,提高代码的可维护性和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值