Spring中IOC的使用(控制反转)

Spring中IOC的使用

IOC(Inverse Of Control)控制反转,它是一种思想,作用就是为了消减我们代码之间的耦合性。它的实现方法就是利用了工厂设计模式。把创建对象的代码从具体的类中剥离出来,交给工厂来完成,从而降低了代码之间的依赖关系

在配置IOC时,spring提供了两个方式,我们先使用XML文件的配置方式来做展开,

导入需要的依赖包spring-context

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-context</artifactId> 
    <version>5.3.1</version>
</dependency>

准备一个Spring的配置文件:beans.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 
	https://www.springframework.org/schema/beans/spring-beans.xsd">
    
</beans>

Spring中的工厂类

BeanFactory是Spring中IOC容器的顶级接口,包含了各种Bean的定义、读取bean配置文档、管理bean的加载、实例化控制bean的生命周期,维护bean之间的依赖关系等功能,其他的容器接口都是它的子类

而我们一般使用的ApplicationContext接口,它作为BeanFactory的派生,除了具有BeanFactory的全部功能外,还有很多重要的功能(国际化、加载多个配置文件、载入多个上下文···等等)。

区别:Bean的创建时间不同:

  • BeanFactory:什么时候用到对象,什么时候创建
  • ApplicationContext:容器启动后,一次性创建了所有的Bean

用到时创建对象:如果Bean中出现异常,用到Bean时才会发现异常;先创建就可以在容器启动时,发现Bean中有没有问题,(同样当Bean较多时,容器的启动较慢)

ApplicationContext接口中的实现类:

  • ClassPathXMLApplicationContext:从类的根路径下加载配置文件,推荐使用
  • FileSystemXMLApplicationContext:从磁盘路径下加载配置文件
  • AnnotationConfigApplicationContext:从一个配置类中创建容器,(使用纯注解的配置类是会用到)

现在我们先使用xml配置的方式完成一个IOC的配置,然后来详细的分析一下bean管理对象的细节

基于XML的IOC配置

准备一个Bean类

public class UserDaoImpl implements IUserDao {

    @Override
    public void save() {
        System.out.println("向数据库中添加一条用户信息");
    }
}

在beans.xml文件中添加配置

    <bean id="userDao" class="com.zxy.dao.impl.UserDaoImpl"/>

测试:

    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserDao userDao = (IUserDao) context.getBean("userDao");
        userDao.save();
    }

默认情况下,它调用的是类中无参的构造方法,如果是没有无参数构造方法的类则不能创建成功

除了上面的方法之外我们还可以使用静态工厂创建对象,和实例工厂创建对象

静态工厂(factory-method

public class StaticFactory {
    public static IUserDao createUserDao(){
        return new UserDaoImpl();
    }
}
    <bean id="userDao2" class="com.zxy.factory.StaticFactory" factory-method="createUserDao"/>

实例工厂(factory-bean+factory-method

public class InstanceFactory {
    public IUserDao createUserDao(){
        return new UserDaoImpl();
    }
}
    <bean id="instanceFactory" class="com.zxy.factory.InstanceFactory"/>
    <bean id="userDao3" factory-bean="instanceFactory" factory-method="createUserDao"/>

几个简单的例子已经写完了,其中springXML配置文件中有一个很重要的标签**<bean/>**,我们来详细的分析一下

Bean标签

作用:配置对象让Spring来创建

常用属性:

  • id:给对象在容器中提供一个唯一的标识,用于获取对象
  • class:指定类的全限定名,用于反射创建对象
  • scope:指定对象的使用范围(作用域)
    • singleton:单例模式(默认)
    • prototype:多例
    • request:web项目中使用,将对象存入request域中
    • session:web项目中使用,将对象存入session域中
  • init-method:指定类中的初始化方法名,对象初始化时执行
  • destroy-method:指定类中的销毁方法名,对象被销毁时执行
getBean方法多种获取Bean的方式
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //根据id属性获取对象
        IUserDao userDao = (IUserDao) context.getBean("userDao");
        //根据字节码获取对象
        IUserDao userDao2 = context.getBean(IUserDao.class);
        //根据bean中的id属性和字节码获取对象(当一个接口有多个实现类时就需要使用这种方式!!)
        IUserDao userDao3 = context.getBean("userDao",IUserDao.class);

补充:

Bean对象的生命周期:

  • 单例对象:scope=“singleton”
    • 一个应用只有一个对象的实例,它的作用范围就是整个应用
    • 对象创建:当应用加载创建容器时,对象就被创建了
    • 对象存活:只要容器在,对象一直存活
    • 对象死亡:当应用卸载,销毁容器时,对象就被销毁
  • 多例对象:scope=“prototype”
    • 每次访问对象时,都会创建一个新的对象
    • 对象创建:当使用对象时,创建对象实例
    • 对象存活:对象被使用一直存活
    • 对象死亡:当对象长时间不用,就会被java垃圾回收器回收

基于注解的IOC配置

bean标签和注解的对应关系:

@Component(类注解,被注解的类表示交给Spring管理)

  • 注解属性value:不写默认为首字母小写的类名,(对应bean标签中的id)
  • 该注解压衍生出三个子注解:效果和@Component一样,只不过是为了体现分层的概念
    • @Controller,适合用在显示层
    • @Service,适合用在业务层
    • @Repository,适合用在数据层

@Scope(对应bean标签中的scope属性)

  • 注解属性value:不写默认Singleton(单例),还可以设置为prototype(多例)

@PostConstruct(对应bean标签中的init-method)

  • 用在方法上,表示类初始化时会执行该方法

@PreDestroy(对应bean标签中的destroy-method)

  • 用在方法上,表示类被销毁时会执行该方法

@PostConstruct和@PreDestroy这两个注解是jdk提供的,需要我们添加相关的依赖

        <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>

在实现类中添加注解:

@Component//表示这个类交给Spring管理
public class UserDaoImpl implements IUserDao {

    @PostConstruct//类被初始化时会执行该方法
    public void initMethod(){
        System.out.println("========init======");
    }

    @Override
    public void save() {
        System.out.println("向数据库中添加一条用户信息");
    }

    @PreDestroy//类被销毁时会执行该方法
    public void destroyMethod(){
        //根据bean的生命周期,destroy执行的时间也不相同
        System.out.println("========destroy======");
    }
}

入口我们暂时还是使用beans.xml文件,所以还需要在beans.xml中写一行代码:

	<!-- 扫描指定包中的注解,从而完成Spring对它们的管理-->
	<context:component-scan base-package="com.zxy"/>

测试:

    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IUserDao userDao = (IUserDao) context.getBean("userDao");
        userDao.save();
    }

DI(依赖注入)是SpringIOC中的一个具体的体现,下一篇Spring中的DI ※

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值