Spring之装配Bean

这是我阅读Spring In Action的记录,如有理解错误的地方,欢迎大家指导。

装配Bean

如何实现Bean装配

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

组件扫描component scanning:Spring会自动发现应用上下文中创建的bean;

自动装配autowiring:Spring自动满足bean之间的依赖;

注解介绍

@Configuration和@ComponentScan

组件扫描不是默认开启的:@Configuration和@ComponentScan注解配合来开启组件扫描;

@ComponentScan:默认会扫描与配置类相同的包以及这个包下所有的子包;

指定扫描的包:@ComponentScan(basePackages = “com.spring.component”)

指定多个扫描的包:@ComponentScan(basePackages = {“com.spring.component”,“com.spring.service”})

指定某些类所在的包为基础扫描包:@ComponentScan(basePackageClasses = {SpringConfigDemo.class, SpringServiceDemo.class})

// 通过java代码定义了spring的装配规则
@Configuration
@ComponentScan  //在spring中启动组件扫描,默认扫描与配置类相同的包以及这个包下的所有子包
public class CDPlayerConfig { 
}

@Component

定义一个可装配的bean:@Component;

为bean命名:@Component(“sgtPeppers”)

@Component
public class SgtPeppers implements CompactDisc {

  private String title = "Sgt. Pepper's Lonely Hearts Club Band";  
  private String artist = "The Beatles";
  
  public void play() {
    System.out.println("Playing " + title + " by " + artist);
  }
  
}

@Autowired

通过为bean添加注解实现自动装配;

通过构造器注入:

@Component
public class CDPlayer implements MediaPlayer {
  private CompactDisc cd;

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

  public void play() {
    cd.play();
  }

}

通过setter方法注入:

@Component
public class CDPlayer implements MediaPlayer {
	private CompactDisc cd;

	public void play() {
		cd.play();
	}

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

}

setter并不重要,可以通过其它名称的方法注入:

@Component
public class CDPlayer implements MediaPlayer {
	private CompactDisc cd;

	public void play() {
		cd.play();
	}

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

}

没有找到要装配的bean会抛出异常,可以通过设置@Autowired(required = false)来避免;

通过Java代码装配Bean

如果要使用的Bean是一个第三方的jar包里面定义的,那个代码里面没有@Component注解,Spring不会自动创建这个实例,并且把它注册到Spring的应用上下文中去,因此,就不能用自动化装配的方案了。

注释掉@ComponentScan,Spring就不会去扫描其它带有@Component注解的Bean并初始化到Spring上下文中去了。这个时候需要使用@Bean注解来初始化Bean到Spring的上下文中去了。

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

public interface CompactDisc {
  void play();
}

public class SgtPeppers implements CompactDisc {

  private String title = "Sgt. Pepper's Lonely Hearts Club Band";  
  private String artist = "The Beatles";
  
  public void play() {
    System.out.println("Playing " + title + " by " + artist);
  }
  
}

还可以使用@Bean(name=“lonelyHeartClubBand”)来给这个Bean指定一个名字。

如果有一个对象依赖sgtPeppers对象,像下面这样:

public interface MediaPlayer {

  void play();

}

public class CDPlayer implements MediaPlayer {
	private CompactDisc cd;

	public CDPlayer(CompactDisc cd) { 
		this.cd = cd; 
	}
	
	public void play() {
		cd.play();
	}

}

就需要像下面这样来初始化该Bean了:

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

有一些值得注意的地方,sgtPeppers方法上面有@Bean注解,这将导致,Spring会拦截所有对它的调用,确保直接返回该方法创建的bean,而不是每次都对其进行实际的调用。

默认情况下,Spring中的bean都是单例的,这样每次返回的都是Spring所创建的bean。

本地运行使用的pom.xml和测试类的写法

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.springdemo</groupId>
  <artifactId>springdemo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springdemo</name>
  <description>how to use spring</description>
  
  <dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aop</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>  	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>  
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>  
	<!-- hibernate, ibatis, mybatis -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-orm</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>
	<!-- 面向切面编程 --> 
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aspects</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jdbc</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>
	<!-- 字节码增强 --> 	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-instrument</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	<!-- 自定义标签 -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	
	<!-- test -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-test</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency> 	
	
	<dependency>
	    <groupId>junit</groupId>
	    <artifactId>junit</artifactId>
	    <version>4.12</version>
	</dependency>

	<dependency>
		<groupId>org.hamcrest</groupId>
		<artifactId>hamcrest-core</artifactId>
		<version>1.3</version>
	</dependency>

	<!-- <dependency>
	  <groupId>com.github.stefanbirkner</groupId>
	  <artifactId>system-rules</artifactId>
	  <version>1.19.0</version>
	</dependency> -->

  </dependencies>
</project>

测试类

package soundsystem;

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class) //测试的时候自动创建应用的上下文
@ContextConfiguration(classes=CDPlayerConfig.class)  //从CDPlayerConfig类中加载
public class CDPlayerTest {
  
  @Autowired
  private CompactDisc cd;
  
  @Autowired
  private CompactDisc sgtPeppers;
	
 
	
  @Test
  public void cdShouldNotBeNull() {
    assertNotNull(cd);
  }

  @Test
  public void play() {
	  //sgtPeppers.play();
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值