Spring - IOC容器

接口及面向接口编程

接口

  • 用于沟通的中介物的抽象化
  • 实体把自己提供给外界的一种抽象化说明,用以由内部操作分离出外部沟通方法,使其能被修改内部而不影响外界其他实体与其交互的方式
  • 对应java接口即声明,声明了哪些方法是对外公开提供的
  • 在Java8中,接口可以拥有方法体

面向接口编程

  • 结构设计中,分清层次及调用关系,每层只向外(上层)提供一组功能接口,各层间仅依赖接口而非实现类。
  • 接口实现的变动不影响各层间的调用,这一点在公共服务中尤为重要
  • “面向接口编程”中的“接口”是用于隐藏具体实现和实现多态性的组件
  • 例子

接口
在这里插入图片描述

实现
在这里插入图片描述

使用
在这里插入图片描述

IOC(控制反转)

概念

  • IOC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护
    • 例子:需要一个房子,不用负责这个房子的图纸设计、建造。我只需要去找开发商、二手房,买来用即可
  • DI(依赖注入)是一种实现方式

  • 目的:创建对象并且组装对象之间的关系

在这里插入图片描述

扩展理解

2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细分析和论证后,他得出答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖”注入(Dependency Injection)“。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

IOC房屋中介

房屋中介

  • 找中介
  • 中介
房屋中介IOC
找中介找IOC容器
中介介绍房子容器返回对象
租房、入住使用对象

Spring的Bean配置

  • 刚才的接口在Spring中的配置方式
<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.imooc.ioc.interfaces.OneInterfaceImpl"></bean>

</beans>

单元测试

  • 下载junit-*.jar 并引入工程
  • 创建UnitTestBase类,完成对Spring配置文件的加载、销毁
  • 所有的单元测试类都继承自UnitTestBase,通过它的getBean方法获取想要得到的对象
  • 子类(具体执行单元测试的类)加注解:
    @RunWith(BlockJUnit4ClassRunner.class)
  • 单元测试方法加注解:@Test
  • 右键选择要执行的单元测试方法执行或者执行一个类的全部单元测试方法

在这里插入图片描述

Bean容器的初始化

  • 基础:两个包
    • org.springframework.beans
    • org.springframework.context
    • BeanFactory提供配置结构和基本功能,加载并初始化Bean
    • ApplicationContext保存了Bean对象并在Spring中被广泛使用
  • 方式,ApplicationContext
    • 本地文件(绝对路径)
    • Classpath(相对路径)
    • Web应用中依赖servlet或Listener

举例:

  • 文件
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:/workspace/appcontext.xml");
  • Classpath
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
  • Web应用
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
	<servlet-name>context</servlet-name>
	<servlet-class>org.springframework.web.context.ContextLoaderSetvlet</servlet-class>
	<load-on-startup>1</load-on-startup>	
</servlet>	

Spring注入

概念

Spring注入是指在启动Spring容器加载bean配置的时候,完成对变量的赋值行为

Spring常用注入方式

设值注入

property:属性
ref:引用

<?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="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceIMpl">
		<property name="injectionDAO" ref="injectionDAO"/>
	</bean>
	
	<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
</beans>	

构造注入

<?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="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceIMpl">
		<consrtuctor-arg name= "injectionDAO" ref= "injectionDAO"/>
	</bean>
	<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
</beans>	

实例

目录结构

在这里插入图片描述

injectionDao
package com.imooc.ioc.injection.dao;

public interface InjectionDao {
    public void save(String arg);
}
InjectionDaoImpl
package com.imooc.ioc.injection.dao;

public class InjectionDaoImpl implements InjectionDao {

    @Override
    public void save(String arg) {
        //模拟数据库保存操作
        System.out.println("保存数据:" + arg);
    }
}
InjectionService
package com.imooc.ioc.injection.service;

public interface InjectionService {
    public void save(String arg);
}
InjectionServiceImpl
package com.imooc.ioc.injection.service;

import com.imooc.ioc.injection.dao.InjectionDao;

public class InjectionServiceImpl implements InjectionService {
    private InjectionDao injectionDao;

    //设值注入
    public void setInjectionDao(InjectionDao injectionDao){
        this.injectionDao = injectionDao;
    }

    //构造器注入
    public InjectionServiceImpl(InjectionDao injectionDao){
        this.injectionDao = injectionDao;
    }

    @Override
    public void save(String arg) {
        //模拟业务操作
        System.out.println("Service接收参数:" + arg);
        arg = arg + ":" +this.hashCode();
        injectionDao.save(arg);
    }
}

spring-injection.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="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
        <property name="injectionDao" ref="injectionDao"></property>
    </bean>

    <bean id="injectionDao" class="com.imooc.ioc.injection.dao.InjectionDaoImpl"/>

</beans>
UnitTestBase
package com.imooc.test.base;

import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;


public class UnitTestBase {
    private ClassPathXmlApplicationContext context;

    private String springXmlpath;

    public UnitTestBase(){}

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

    @Before
    public void befor(){
        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;
        }

    }
}
TestInjection
package com.imooc.test.base;

import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;


public class UnitTestBase {
    private ClassPathXmlApplicationContext context;

    private String springXmlpath;

    public UnitTestBase(){}

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

    @Before
    public void befor(){
        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;
        }

    }
}
结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值