Spring 通过Java代码装配bean

简介:

1. 背景

书接上文Spring自动化装配bean

尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化扫描配置是更为推荐的方式,但在有些情况下自动化扫描的方案行不通,如想要将第三方库中的组件装配到自己的应用中。在这种情况下必须通过显示 装配的方式。

显示装配有两种可选方案:Java和XML。JavaConfig是更好的方案:更强大、类型安全并对重构友好。因他就是Java代码。

2. 代码 & 解说

接口: CompactDisc.java

package soundsystem;

public interface CompactDisc {
  void play();
}

接口: MediaPlayer.java

package soundsystem;

public interface MediaPlayer {
  void play();
}

 

SgtPeppers.java

复制代码
package soundsystem;

public class SgtPeppers implements CompactDisc {

  private String title = "Sgt. Pepper's Lonely Hearts Club Band";  
  private String artist = "The Beatles";

  @Override
  public void play() {
    System.out.println("Playing " + title + " by " + artist);
  }

}
复制代码

注:区别与自动转配,这里去掉了@compenent注解

CDPlayer.java

复制代码
package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;

public class CDPlayer implements MediaPlayer {
  private CompactDisc cd;

  @Autowired
  public CDPlayer(CompactDisc cd) {
    this.cd = cd;
  }

  @Override
  public void play() {
    cd.play();
  }
}
复制代码

 

借助JavaConfig实现注入

CDPlayerConfig.java

复制代码
package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDPlayerConfig {
  
  @Bean
  public CompactDisc compactDisc() {
    return new SgtPeppers();
  }

  @Bean
  public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
  }
}
复制代码

注:区别与自动装配,这里去掉了@ComponentScan注解,而是显式的声明了Bean。@Bean注解告诉了Spring上下文这个方法会将返回一个对象,该对象要注册为Spring应用上下文中的bean,方法体重包含了最终产生bean实例的实现逻辑。

测试CDPlayerTest.java

复制代码
package soundsystem;

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;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest {

  @Autowired
  private MediaPlayer player;

  @Test
  public void play() {
    player.play();
  }
}
复制代码

3. 深入了解JavaConfig

别于上面代码中的实现方式,还可以这样配置JavaConfig

复制代码
package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDPlayerConfig {
  
  @Bean
  public CompactDisc sgtPeppers() {
    return new SgtPeppers();
  }

  @Bean
  public CDPlayer cdPlayer() {
    return new CDPlayer(sgtPeppers());
  }
}
复制代码

cdPlayer没有使用默认的构造函数,而是调用了CompactDisc对象。看起来是通过调用sgtPeppers()得到的,实际不是这样的。原因是sgtPeppers方法是上添加了@Bean注解,Spring将会拦截所有对它的调用,而是直接返回方法所创建的bean,而不是每次都对其进行实际的调用。以下为证

复制代码
@Bean
public CDPlayer() {
    return new CDPlayer(sgtPeppers());
} @Bean
public anotherCDPlayer() { return new CDPlayer(sgtPeppers());
}
复制代码

假如每次都调用sgtPeppers()方法,那么每个CDPlayer实例将会有一个特有的SgtPepper实例,但实际上是相同的实例。

相比于前面代码中的声明方式,还是推荐上述代码中的方式,那样更容易理解。如

复制代码
  @Bean
  public CompactDisc compactDisc() {
    return new SgtPeppers();
  }

  @Bean
  public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
  }
复制代码

这种方法不用明确引用@Bean方法也能将CompactDisc注入到CDPlayer的构造器中。这种方式是引用其他bean的最佳方式,它不需要要求将CompactDisc必须在JavaConfig中声明。






本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/p/6984234.html,如需转载请自行联系原作者


相关文章
|
10月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
625 6
|
11月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
1307 3
|
10月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
411 115
|
10月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
310 98
|
10月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
10月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
551 94
|
10月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
719 43
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
786 70
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
297 1
|
JavaScript 前端开发 网络协议
WebSocket在Java Spring Boot+Vue框架中实现消息推送功能
在现代Web应用中,实时消息提醒是一项非常重要的功能,能够极大地提升用户体验。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为实现实时消息提醒提供了高效且低延迟的解决方案。本文将详细介绍如何在Java Spring Boot后端和Vue前端框架中利用WebSocket实现消息提醒功能。
2402 127