Spring第二讲:SpringIoC控制反转、依赖注入

四、Spring IoC

4、1什么是IoC

在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里,开发者通过XML或注解的配置将Java对象的管理权交给IoC容器,对象的创建由Spring完成。当开发者需要用到对象时,可以直接从Spring中获取对象,不需要再自行创建。

IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本开发者是主动的一方,它想要使用什么资源就会自己创建。但在 Spring 应用中,IoC 容器掌握着主动权,开发者则变成了被动的一方,等待 IoC 容器创建对象后使用。

在应用开发中,并不是所有对象都交给Spring创建,开发者经常将功能类的对象交给Spring去创建,这些类的对象创建后只需要调用功能,实现功能即可,但实体对象,因为每次创建存储的数据或代表的内容都不尽相同,所以实体类的对象还是使用常规方式(new)来实现对象创建。

4、2Spring加载Bean

DAO层

public interface IDemoDAO {
  public void show();
}

public class DemoDAO implements IDemoDAO {
  @Override
  public void show() {
    System.out.println("我是DAO方法");
  }
}

Service层

public interface IDemoService {
  public void show();
}

public class DemoService implements IDemoService {

  private IDemoDAO demoDAO=new DemoDAO();

  @Override
  public void show() {
    demoDAO.show();
  }
}

在applicationContext.xml中添加Bean配置


<bean id="demoDAO" class="com.demo.DAO.Impl.DemoDAO">bean>
<bean id="demoService" class="com.demo.service.Impl.DemoService">bean>

获取IoC创建的对象

//创建ApplicationContext,通过实例化ClassPathXmlApplicationContext获取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
//getBeanDefinitionNames获取配置文件中所有加载的Bean
String[] str=applicationContext.getBeanDefinitionNames();
for (String s : str) {
  System.out.println(s);
}
//getBean通过Bean的id属性获取对象
IDemoService demoService1= (IDemoService) applicationContext.getBean("demoService");
demoService1.show();

4、3Spring注入对象

通过案例可以看到Spring通过配置,为我们创建了对象,但是目前我们遇到了问题,问题就是,我们在实现过程中,Service要引用DAO的对象进行功能实现,我们的DAO虽然交给了Spring去创建,但我们依旧需要手动创建,也就是说我们要想实现功能,在Service中就要依赖于DAO的对象实现功能,这样的形式,我们也可以交给Spring帮我们解决,这就是SpringIoC中重要的功能—依赖注入(DI)

在applicationContext.xml中进行修改

<bean id="demoDAO" class="com.demo.DAO.Impl.DemoDAO">bean>
<bean id="demoService" class="com.demo.service.Impl.DemoService">
  
  <property name="demoDAO" ref="demoDAO"/>
bean>

Service类修改

public class DemoService implements IDemoService {
  
  private IDemoDAO demoDAO;

  public void setDemoDAO(IDemoDAO demoDAO) {
    this.demoDAO = demoDAO;
  }

  @Override
  public void show() {
    demoDAO.show();
  }
}

4、4使用注解实现IoC

通过配置文件实现SpringIoC,可以很好的分离代码和配置,有较高的解耦性,但操作较为繁杂,所以Spring又提供了以注解形式对IoC进行配置的方式,虽然解耦性降低,但代码实现较为轻便。

IoC核心注解:

  • @Component 组件,通用的注解方式
  • @Service 在业务逻辑层使用(service层)
  • @Repository 在数据访问层使用(DAO层)
  • @Controller 在控制层使用,控制器的声明(Controller)
  • @Autowired:用来实现依赖注入,Autowired会通过对象类型进行注入,如在一个类中出现相同数据类型对象需要注入时,需要配合@Qualifier(对象名)进行组合注解进行注入
  • @Resource:用来实现依赖注入,Resource会先根据名称查找要注入的对象,在根据对象类型查找注入对象,根据名称查找时,可以通过Resource的name属性查找

applicationContext.xml文件配置


<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">
  
  <context:component-scan base-package="com.demo"/>
beans>

DAO层

@Repository
public class DemoDAO implements IDemoDAO {
  @Override
  public void show() {
    System.out.println("我是DAO方法");
  }
}

Service层

@Service
public class DemoService implements IDemoService {

  //@Autowired
  //@Qualifier("demoDAO")
  @Resource
  private IDemoDAO demoDAO;

  /*
  public void setDemoDAO(IDemoDAO demoDAO) {
    this.demoDAO = demoDAO;
  }
  */

  @Override
  public void show() {
    demoDAO.show();
  }
}

获取IoC对象

//创建ApplicationContext,通过实例化ClassPathXmlApplicationContext获取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
//getBeanDefinitionNames获取配置文件中所有加载的Bean
String[] str=applicationContext.getBeanDefinitionNames();
for (String s : str) {
  System.out.println(s);
}
//getBean通过Bean的id属性获取对象
IDemoService demoService1= (IDemoService) applicationContext.getBean("demoService");
demoService1.show();

4、5Resource注解和Autowired注解的区别

@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 项目中),但二者却有着不同:

  • 来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于Java
  • 依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询
  • 支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数
  • 依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入

你可能感兴趣的:(Spring,spring,java,后端,开发语言)