Spring依赖注入的三种方式小结

作者:飞扬小初 时间:2022-08-09 15:56:41 

Spring的主要特性包括IOC和DI,其中DI是IOC的基础。在以前的Spring使用过程中大部分都是使用XML配置文件显式配置spring组件,导致大量的XML配置文件以及冗余的XML配置代码。阅读《Spring in Action》后总结Spring的DI功能的三种主要装配方式以及混合装配方式

根据注解自动装配

Spring中有非常丰富的注解,通过这些注解可以方便地配置Spring容器,使得Spring容器可以自动识别相关Bean并做自动注入装配。

使用注解

  • @Component注解:标注一个类,标识此类为一个Java Bean。

  • @Configuration注解:标注一个类,标识此类为一个Java配置类

  • @ComponentScan注解:标注一个类,用以配置扫描的包名称

示例代码

这里使用一个最简单的例子来展示自动装配的配置,代码结构如图所示。

Spring依赖注入的三种方式小结

ActionConfig类用于做全局配置,我们知道,一名骑士一般都会有一匹马,所以这里Horse和Knight类作为Java Bean被Spring容器创建,并将Horse类的一个bean注入到Knight中。所以在Horse和Knight中必须使用@Component注解进行修饰。

Knight代码:


package entities;

import org.springframework.stereotype.Component;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Component
public class Knight {
 private Horse horse;

Knight(Horse horse){
   this.horse = horse;
 }

public void ride(){
   horse.bark();
 }
}

Horse代码:


package entities;

import org.springframework.stereotype.Component;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Component
public class Horse {
 void bark(){
   System.out.println("Horse!!!!");
 }
}

ActionConfig代码:


package config;

import entities.Knight;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
@ComponentScan(basePackageClasses = {Knight.class})
public class ActionConfig {
}

这里的ComponentScan注解内的属性用以注明Knight类所在的包为扫描的基础包。凡是这个基础包及其子包内的标注了@Component的类都将被视为Java Bean,这些Bean被Spring容器创建和管理。

Java配置类装配

从自动装配的代码中,可以看出自动装配是非常简单方便的。Java配置类进行装配的方式是采用对配置类中的方法进行注解标注,实现bean的创建和管理。

还是采用以上的例子,现在我们将上面的自动装配改成Java配置类进行装配。

首先,删掉Knight和Horse中的@Component注解,删掉ActionConfig中的@ComponentScn注解,因为这些注解都是自动装配才需要的。


package entities;

/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Knight {
 private Horse horse;

public Knight(Horse horse){
   this.horse = horse;
 }

public void ride(){
   horse.bark();
 }
}

package entities;

/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Horse {
 void bark(){
   System.out.println("Horse!!!!");
 }
}

ActionConfig类:


package config;

import entities.Horse;
import entities.Knight;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
public class ActionConfig {
 @Bean
 public Knight getKnight(){
   return new Knight(getHorse());
 }
 @Bean
 public Horse getHorse(){
   return new Horse();
 }
}

通过@Bean注解对相关的方法进行修饰,Spring就可以知道调用这些方法来构建相应的bean,并注入到依赖的对象中。

XML配置文件装配

使用XML配置文件来装配组件是最为繁琐的,需要对各个bean做一一配置,特别是需要配置构造器或者setter的参数。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

以上是一个空的XML配置文件,看一下就知道,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" xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 <bean id="knight" class="entities.Knight">
   <constructor-arg ref="horse"></constructor-arg>
 </bean>

<bean id="horse" class="entities.Horse"></bean>
</beans>

通过配置两个bean元素,并且通过constructor-arg元素来配置构造函数注入的bean,达到依赖注入的目的。

导入和混合配置

有时候单纯的XML配置或者Java配置不满足我们的需求怎么办呢?Spring支持混合配置的方式来管理bean,通过Java和XML配置的混合,达到你想要的效果。

Java配置中引用Java配置

在配置类中使用@Import注解进行引入另一个Java配置类。


package config;

import entities.Horse;
import entities.Knight;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
@Import(BeautyConfig.class)
public class ActionConfig {
 @Bean
 public Knight getKnight(){
   return new Knight(getHorse());
 }
 @Bean(name = "horse")
 public Horse getHorse(){
   return new Horse();
 }
}

BeautyConfig代码:


package config;

import entities.Beauty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
public class BeautyConfig {
 @Bean
 Beauty getBeauty(){
   return new Beauty();
 }
}

在Main中,只需要通过ActionConfig就可以获取到所有的上下文对象。


package main;

import config.ActionConfig;
import entities.Beauty;
import entities.Knight;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Main {
 public static void main(String[] args) {
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ActionConfig.class);
   Knight knight = context.getBean(Knight.class);
   knight.ride();
   Beauty beauty = context.getBean(Beauty.class);
   beauty.sleep();
 }
}

这里简单使用Import引入了另一个配置的Java文件,就实现了将多个bean分别配置到多个Java配置类中。

Java配置中引入XML配置

在Java中引入xml配置的基本方法与引入Java代码配置类似,只需要将@Import改为@ImportResource,配上xml的文件地址即可。


@ImportResource("classpath:spring.xml")

以上,就是Java配置spring依赖注入的方法。

XML配置中引入XML配置

同理,在XML配置中引入XML也需要使用Import,但是在XML中是import标签,通过使用import标签导入另一个xml文件。

这里我新建了一个another.xml的文件,用以作为另一个配置文件示例。在原有的spring.xml中加入以下代码:


<import resource="another.xml"></import>

这样就简单导入了anoter.xml配置文件。

XML配置中引入Java配置

乍看之下,在XML中似乎没有标签可以导入Java配置类的,不过任何Java配置类都是一个bean,所以可以通过配置bean标签来导入Java配置类!


<bean class="config.BeautyConfig"></bean>

通过在XML中配置这个Java配置类的bean,就直接导入了在Java配置类中的所有bean,真是神奇!

以下是配置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" xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 <import resource="another.xml"></import>
 <bean class="config.BeautyConfig"></bean>
 <bean id="knight" class="entities.Knight">
   <constructor-arg ref="horse"></constructor-arg>
 </bean>

<bean id="horse" class="entities.Horse"></bean>
</beans>

来源:http://www.jianshu.com/p/b6286cfb3f34?utm_source=tuicool&utm_medium=referral

标签:Spring,依赖注入
0
投稿

猜你喜欢

  • java jdbc连接和使用详细介绍

    2023-01-13 18:12:52
  • jar包运行时提示jar中没有主清单属性的解决

    2023-11-23 19:04:10
  • 使用Spring Security OAuth2实现单点登录

    2023-08-13 01:44:34
  • Java实现接口的枚举类示例

    2023-06-18 01:22:04
  • Java热门笔试试题整理

    2023-11-25 08:56:33
  • 基于SpringBoot实现用户身份验证工具

    2022-05-08 18:37:29
  • java 字段值为null,不返回该字段的问题

    2023-07-13 10:32:34
  • windows下java -jar 后台运行以及杀死后台进程的操作

    2022-02-09 17:28:13
  • Spring Cloud Eureka 服务上下线监控的实现

    2022-02-18 21:06:15
  • Flutter Widgets MediaQuery控件屏幕信息适配

    2023-06-29 04:48:21
  • Java创建随机数的四种方式总结

    2022-05-11 10:29:17
  • java模拟实现双向链表

    2022-06-05 09:16:16
  • 如何只返回实体类中的部分字段问题

    2022-11-28 05:09:53
  • 浅谈java多线程wait,notify

    2023-11-29 16:29:03
  • 深入了解Spring中最常用的11个扩展点

    2023-07-05 17:46:40
  • Java实现的不同图片居中剪裁生成同一尺寸缩略图功能示例

    2023-08-23 14:53:15
  • 解析JAVA深度克隆与浅度克隆的区别详解

    2023-11-02 10:57:28
  • Java序列化和反序列化示例介绍

    2023-11-25 04:24:26
  • 解决ThingsBoard编译报错问题:Failure to find org.gradle:gradle-tooling-api:jar:6.3

    2021-11-20 16:24:22
  • java中Scanner输入用法实例

    2023-09-03 18:25:36
  • asp之家 软件编程 m.aspxhome.com