Spring容器负责创建应用程序中的bean同时通过ID来协调这些对象之间的关系。作为开发人员,我们需要告诉Spring要创建哪些bean并且如何将其装配到一起。

spring中bean装配有两种方式

  • 隐式的bean发现机制和自动装配
  • 在java代码或者XML中进行显示配置

当然这些方式也可以配合使用。

我们测试代码如下

CompactDisc和MediaPlayer是两个接口 其中MediaPlayer的构造方法参数类型为CompactDisc。
我们主要测试CompactDisc和MediaPlayer的实现有没有注入进来,同时MediaPlayer接口对于CompactDisc的依赖有没有满足
package com.zcs;

import com.zcs.service.CompactDisc;
import com.zcs.service.MediaPlayer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull; @RunWith(SpringJUnit4ClassRunner.class)
//XML配置
//@ContextConfiguration(locations ="spring-config.xml")
//Java代码配置
@ContextConfiguration(classes =CDPlayerConfig.class)
public class CDPlayerTest {
@Autowired
private CompactDisc cd;
@Autowired
private MediaPlayer player;
@Test
public void cdShouldNotBeNull(){
assertNotNull(cd);
}
@Test
public void play(){
assertEquals("Playing 哎呦不错哦 by 周杰伦",player.play());
} }

1、自动化装配

Spring从两个角度来实现自动化装配:

组件扫描(ComponentScan):自动发现应用上下文中所创建的bean

自动装配(Autowired):自动满足bean之间的依赖

CompactDisc接口类和实现类:

public interface CompactDisc {
String play();
}
@Component
public class SgtPeppers implements CompactDisc {
private String title="哎呦不错哦";
private String artist="周杰伦";
@Override
public String play() {
return "Playing "+title+" by "+artist;
}
}

MediaPalyer接口类和实现类

public interface MediaPlayer {
String play();
}
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd ;
@Autowired
public CDPlayer(CompactDisc cd){
this.cd=cd;
}
@Override
public String play(){
return cd.play();
}
}

配置类CDPlayerConfig:

@Configuration
@ComponentScan
public class CDPlayerConfig { }

@ComponentScan作用是扫描带有@Component注解的类,并为其创建bean。默认是扫描同一包下的类,当然也可以加入参数,指定包名。

如@ComponentScan(basePackages={"com.zcs"})或者@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class})(即这些类所在的包)

@Autowired满足自动依赖装配,可以作用在任何方法上面。

XML形式的自动装配则修改测试类@ContextConfiguration,改成加载spring-config.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: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">
<bean id="compactDisc" class="com.zcs.impl.SgtPeppers"></bean>
<bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
<constructor-arg ref="compactDisc"></constructor-arg>
</bean>
<context:component-scan base-package="com.zcs">
</beans>

 2、显示bean装配

当想要将第三方库中的组件装配到你的应用中,在这种情况下是没有办法在它的类上面添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案。

只能选择java代码或者xml显示配置

首先可以把两个实现类上的@Component,还有配置类中的@ComponentScan,CDPlayer类中方法上的@Autowired注解去掉。

这个时候测试应该都通不过。

Java代码方式:修改CDPlayerConfig配置类为:

@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc sgtPeppers(){
return new SgtPeppers();
}
@Bean
public MediaPlayer getCDPlayer(){
return new CDPlayer(sgtPeppers());
}
   //@Bean
//public MediaPlayer getCDPlayer(CompactDisc compactDisc){
// return new CDPlayer(compactDisc);
//}
}

再运行测试应该会通过了,解释下 @Bean注解告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终生成bean实列的逻辑。

第二个方法故意写的奇怪一点,看起来CompactDisc是通过调用sgtPeppers()方法得到的,但并非如此,Spring会拦截对sgtPeppers方法的调用,转而从上下文中直接获取该方法所创建的bean,而不是每次都对其进行实际的调用。

比如:再添加一个方法(测试会通不过)

   @Bean
public MediaPlayer anotherCDPlayer() {
return new CDPlayer(sgtPeppers());
}

这两个方法依赖注入的CompactDisc将会是同一个bean。

当然通过情况下用注释的方法更容易理解一点。

XML方式:

首先CDPlayerTest为XML方式,同时修改spring-config.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: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">
<bean id="compactDisc" class="com.zcs.impl.SgtPeppers"></bean>
<bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
<constructor-arg ref="compactDisc"></constructor-arg>
    </bean>
<context:component-scan base-package="com.zcs"/>
</beans>

组件扫描方式的配置不去掉也是没影响的。

补充:

复杂一点的构造方法

修改SgtPeppers的构造方法

public class SgtPeppers implements CompactDisc {
private String title="哎呦不错哦";
private String artist="周杰伦";
private List<String> tracks=new ArrayList<>(); public SgtPeppers(String title, String artist, List<String> tracks) {
this.title = title;
this.artist = artist;
this.tracks = tracks;
} @Override
public String play() {
return "Playing "+title+" by "+artist;
}
}

同时修改spring-config.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: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">
<bean id="compactDisc" class="com.zcs.impl.SgtPeppers">
<constructor-arg index="0" value="雪狼湖"/>
<constructor-arg index="1" value="张学友"/>
<constructor-arg index="2">
<list>
<value>不老的传说</value>
<value>爱是永恒</value>
</list>
</constructor-arg>
</bean>
<bean id="cdPlayer" class="com.zcs.impl.CDPlayer">
<constructor-arg ref="compactDisc"></constructor-arg>
</bean>
<context:component-scan base-package="com.zcs"/>
</beans>

还有属性注入<property>,c和p命名空间使用就不细说了。对于xml的配置一般在java代码中也会有对应的配置。但显示配置用java代码会类型安全一点

参考:spring实战第4版

spring Bean装配的几种方式简单介绍的更多相关文章

  1. Spring Bean定义的三种方式

    <!--Spring容器启动配置(web.xml文件)--> <context-param> <param-name>contextConfigLocation&l ...

  2. spring bean实例化的三种方式

    一.使用类的无参构造创建 配置文件 java代码 注意若类里面没有无参的构造,则会出现异常 二.使用静态工厂创建 配置文件 java代码 Factory类 测试类 结果 三.使用实例工厂 配置文件 1 ...

  3. H5页面前后端通信 (3种方式简单介绍)

    1.ajax:短连接 2.websocket :长连接,双向的.   node搭建的websocket服务器,推送信息给客户端浏览器 :https://www.cnblogs.com/fps2tao/ ...

  4. Spring中bean实例化的三种方式

    之前我已经有好几篇博客介绍Spring框架了,不过当时我们都是使用注解来完成注入的,具体小伙伴可以参考这几篇博客(Spring&SpringMVC框架案例).那么今天我想来说说如何通过xml配 ...

  5. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  6. Spring——自动装配的三种实现方式

    依赖注入的本质是装配,装配是依赖注入的具体行为 spring会在上下文中自动寻找,并自动给bean装配属性 自动装配的三种方式 (1).在xml中显式的装配 (2).在java中显式的装配 (3).隐 ...

  7. Spring bean管理器 bean实例化的三种方式

    bean实例化的三种方式实现 第一种:使用类的无参数构造方法创建(常用 重要) 第一种实例化方式最常用,实例化类时会通过调用无参构造方法创建.示例代码如下: package spring.com.Us ...

  8. spring中创建bean对象的三种方式以及作用范围

    时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...

  9. 【Spring】的【bean】管理(XML配置文件)【Bean实例化的三种方式】

    Bean实例化的三种方式 说明:通过配置文件创建对象就称为Bean实例化. 第一种:使用类的无参构造创建(重点) 实体类 package com.tyzr.ioc; public class User ...

随机推荐

  1. 关于Unity中的transform组件(二)

    在Scene视图中的蓝色网格,每一格默认是1米 一.沿着Z轴每秒移动10米 Transform cube_trans; void start(){ this.cube_trans=this.trans ...

  2. Ubuntu 16.04 更换阿里云源

    Ubuntu 16.04 更换阿里云源sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份sudo gedit /etc/apt/so ...

  3. 【noip模拟题】日历游戏(博弈论+搜索)

    直接搜索即可... 注意不要爆栈..所以我们可以分块搜索... 然后太懒且太弱我就不写了... orz hzwer http://hzwer.com/4954.html [问题描述] moreD和mo ...

  4. iframe超时处理。。。。

    function iframeTimeOut(url, timeOut_callback, width, height) { /// <summary> /// iframe超时处理 // ...

  5. 漫游Kafka入门篇之简单介绍(1)

    介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计.这个独特的设计是什么样的呢?   首先让我们看几个基本的消息系统术语: Kafka将消息以 ...

  6. .NET基础知识(一、认识.Net)

    参考链接:http://blog.csdn.net/shanyongxu/article/details/50849111 认识.NET平台 可能很多人问什么是.NET框架,它包含了哪些内容?为开发程 ...

  7. 深入了解Java之虚拟机内存

    在讨论JVM内存区域分析之前,先来看一下Java程序详细运行的过程: -我们今天就来分析一下Java程序运行过程的-Runtime-Data-Area(运行时数据)-这一块" class=& ...

  8. php实现简单的流程管理

    流程管理,在各种系统中扮演很重要的地位,可以把设定好的流程放入系统中,规定好几个节点,只要所有节点都通过,就可以通过. 惯例,先看数据库: 我们首先做一个新建流程页面,先把节点做好 xinjian.p ...

  9. python反序列化研究学习

    零.补充: 补充于2018-02-08,之前研究时候有一个疑惑,python的序列化成二进制,打web服务怎么传这个二进制对象呢,今天请教了身边大神(传说的九零后黑客代表),可以使用base64传输. ...

  10. ie8兼容:对象不支持“trim”属性或方法

    trim() 方法是原生js中去空格的方法,高版本浏览器已经默认支持trim() 方法,但ie8以下不支持,会报错:对象不支持“trim”属性或方法 解决这个的兼容,只需要扩展String原型属性 在 ...