Spring核心思想之一 —— IOC/DI的实现方式

本文详细介绍了如何在Spring框架中通过配置文件、注解结合和创建Config类的方式实现依赖注入和控制反转。涵盖了三层架构的bean加载实例,以及Spring中常见的注解如@Component、@Repository、@Service和@Controller的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

概述

一、配置文件加载bean

二、注解和配置文件结合加载bean

三、Config类和注解结合加载bean

四、Spring框架中常见的注解


概述

IOC(控制反转)是Spring框架的核心思想之一,主要用于解耦。IOC是指将创建对象对象的权利转移给Spring框架进行管理。由Spring框架根据配置文件或注解等方式,创建bean对象并管理各个bean对象之间的依赖关系,使之形成松散耦合的关系,实现解耦。

DI(依赖注入)是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个bean对象都依赖IOC容器注入当前bean对象所需要的另外一个bean对象。

在本篇博客中使用配置文件方式、注解和配置文件结合的方式以及创建Config类和注解结合的方式来实现IOC/DI。

一、配置文件加载bean

使用简单的案例:三层模式之间的串联调用。

数据访问层:IDao接口和DaoImp实现类(分别创建):

public interface IDao {
    void print();
}
//--------------------------------------------
public class DaoImp implements IDao{
    @Override
    public void print() {
        System.out.println("===数据访问层===");
    }
}

业务层:IService接口和ServiceImp实现类:

public interface IService {
    void print();
}
//-------------------------------------------
public class ServiceImp implements IService{

    IDao dao;

    public void setDao(IDao dao) {
        this.dao = dao;
    }

    @Override
    public void print() {
        System.out.println("===业务层==");
        dao.print();
    }
}

 控制器层:IController接口和ControllerImp实现类:

public interface IController {
    void print();
}
//-------------------------------------------------
public class ControllerImp implements IController{

    IService service;

    public void setService(IService service) {
        this.service = service;
    }

    @Override
    public void print() {
        System.out.println("===控制器层===");
        service.print();
    }
}

Test类: 

public class Test {
    public static void main(String[] args) {
        // 加载配置文件applicationContext.xml
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取id为controllerImp的bean对象,创建类型为IController的对象实例
        IController controller = (IController) applicationContext.getBean("controllerImp");
        controller.print();
    }
}

applicationContext.xml配置文件:

ref属性:注入当前bean对象所依赖的另一个bean对象。

    <!--注入DaoImp类-->
    <bean id="daoImp" class="com.dytx.dao.DaoImp"></bean>

    <!--注入ServiceImp-->
    <bean id="serviceImp" class="com.dytx.service.ServiceImp">
        <property name="dao" ref="daoImp"></property>
    </bean>

    <!--注入ControllerImp-->
    <bean id="controllerImp" class="com.dytx.controller.ControllerImp">
        <property name="service" ref="serviceImp"></property>
    </bean>

 执行结果:

 从上述代码的执行结果可以看出我们通过配置文件成功加载了bean对象,代码的可读性很强

二、注解和配置文件结合加载bean

在敲代码之前我需要了解几个Spring中常见的注解:

@Conponent:标注任意类为Bean;

@Repository:定义数据访问层Bean的注解;

@Service:定义业务层Bean的注解;

@Controller:定义控制器层Bean的注解;

@Autowired:用于依赖注入,是替代配置文件中的ref属性。

注意:使用@Conponent、@Repository、@Service、@Controller注解时需要配合配置文件中的

<context:component-scan>标签。

使用简单的案例:三层模式之间的串联调用。

三个接口、Test类与上述代码一致,只需在实现类和配置文件作出改动。

DaoImp实现类:

@Repository
public class DaoImp implements IDao{
    @Override
    public void print() {
        System.out.println("===数据访问层===");
    }
}

ServiceImp实现类:

@Service
public class ServiceImp implements IService{

    @Autowired
    IDao dao;

    @Override
    public void print() {
        System.out.println("===业务层==");
        dao.print();
    }
}

ControllerImp实现类:

@Controller
public class ControllerImp implements IController{

    @Autowired
    IService service;

    @Override
    public void print() {
        System.out.println("===控制器层===");
        service.print();
    }
}

 applicationContext.xml配置文件:

<context:component-scan>标签可根据写入的包名,扫描指定包及其子包中的所有“类”,并为添加了 @Component(组件),@Service(服务),@Controller(控制器),@Repository(数据仓库)修饰的类创建对象并存入IoC容器。

<context:component-scan base-package="com.dytx"></context:component-scan>

执行结果:

  

从上述代码的执行结果可以看出我们通过注解以及配置文件成功加载了bean对象,代码简洁,但是可读性相对于只使用配置文件的方式较差。

三、Config类和注解结合加载bean

在敲代码之前我需要了解几个Spring中常见的注解:

@Configuration:声明配置类;

@Bean:用于某个方法,通过@Bean注解告诉Spring IOC容器,该方法的返回值实例是一个Bean。

利用配置类来加载bean对象时,我们不需要配置文件,Test类、ServiceImp类、ControllerImp类以及DaoImp类中的代码需要做出改动,其它代码不做改动。

SpringConfig类:

@Configuration
public class SpringConfig {
    @Bean
    //DaoImp类所对应的bean对象,默认id为daoMethod
    public IDao daoMethod() {
        return new DaoImp();
    }

    @Bean
    //ServiceImp类所对应的bean对象,默认id为serviceMethod
    public IService serviceMethod() {
        return new ServiceImp(daoMethod());
    }

    @Bean
    //ControllerImp类所对应的bean对象,默认id为controllerMethod
    public IController controllerMethod() {
        return new ControllerImp(serviceMethod());
    }
}

 DaoImp类:

public class DaoImp implements IDao{
    @Override
    public void print() {
        System.out.println("===数据访问层===");
    }
}

ServiceImp类:

public class ServiceImp implements IService{

    IDao dao;

    public ServiceImp(IDao dao) {
        this.dao = dao;
    }

    @Override
    public void print() {
        System.out.println("===业务层==");
        dao.print();
    }
}

ControllerImp类:

public class ControllerImp implements IController{

    IService service;

    public ControllerImp(IService service) {
        this.service = service;
    }

    @Override
    public void print() {
        System.out.println("===控制器层===");
        service.print();
    }
}

Test类:

public class Test {
    public static void main(String[] args) {
        // 加载配置类的Class对象
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        //获取id为controllerImp的bean对象,创建类型为IController的对象实例(默认id为方法名首字母小写后的全名)
        IController controller = (IController) applicationContext.getBean("controllerMethod");
        controller.print();
    }
}

执行结果:

 从上述代码的执行结果可以看出我们通过配置类和注解的方式成功加载了bean对象。

四、Spring框架中常见的注解

(1)用于声明bean注解

@Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注;

@Repository:定义数据访问层Bean的注解;

@Service:定义业务层Bean的注解;

@Controller:定义控制器Bean的注解。

(2)用于注入的注解
@Autowired:按类型自动注入;

@Qualifier:按名称自动注入。

(3)声明配置、扫描、启用特性的注解
@Configuration:声明配置类;

@ComponentScan:组件扫描;
@EnableScheduling:启用任务调度;
@EnableAspectJAutoProxy:启用自动代理工厂。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值