spring装配bean的三种方式及其混合装配
在spring容器中装配bean有三种基本方式和混合装配方式:
- 隐式的bean自动发现机制和自动装配
- 在java中进行显式配置
- 在xml中配置
- 混合装配(在多个java文件中配置、在JavaConfig中引用XML配置、在XML中引用JavaConfig配置)
一、使用自动化方式装配bean示例:
1:创建maven项目并引入依赖:
<?xml version="1.0" encoding="UTF-8"?> <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.springinaction.cn</groupId>
<artifactId>BeanWiring</artifactId>
<version>1.0-SNAPSHOT</version> <name>BeanWiring</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
</dependencies> <build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2:创建简单java类接口及其实现,并将其实现类增加@Component注解,spring容器将为这个类创建bean:
package com.springinaction.cn; public interface CompactDisc {
public void play();
}
package com.springinaction.cn; import org.springframework.stereotype.Component; @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);
}
}
3:创建配置类,启用组件扫描:
package com.springinaction.cn; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan
public class CDPlayerConfig {
}
至此,可被被spring自动装配的bean已经创建好了,用junit测试一下:
package com.springinaction.cn; 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 CompactDisc cd; @Test
public void cdShouldNotBeNull(){
cd.play();
} }
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/bin/java -ea -Didea.test.cyclic.buffer.size=10485760 "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60362:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit-rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit5-rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/tools.jar:/Users/zhenghongbo/IdeaProjects/BeanWiring/target/test-classes:/Users/zhenghongbo/IdeaProjects/BeanWiring/target/classes:/Users/zhenghongbo/Documents/apache-maven-local-repo/junit/junit/4.12/junit-4.12.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-aop/4.3.1.RELEASE/spring-aop-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-beans/4.3.1.RELEASE/spring-beans-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-core/4.3.1.RELEASE/spring-core-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-context/4.3.1.RELEASE/spring-context-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-expression/4.3.1.RELEASE/spring-expression-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-test/4.3.5.RELEASE/spring-test-4.3.5.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-jdbc/4.3.5.RELEASE/spring-jdbc-4.3.5.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-tx/4.3.5.RELEASE/spring-tx-4.3.5.RELEASE.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.springinaction.cn.CDPlayerTest,cdShouldNotBeNull
Jun 19, 2019 9:35:10 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
Jun 19, 2019 9:35:10 PM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
Jun 19, 2019 9:35:10 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@2d6e8792, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2812cbfa, org.springframework.test.context.support.DirtiesContextTestExecutionListener@2acf57e3, org.springframework.test.context.transaction.TransactionalTestExecutionListener@506e6d5e, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@96532d6]
Jun 19, 2019 9:35:10 PM org.springframework.context.support.GenericApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@4590c9c3: startup date [Wed Jun 19 21:35:10 CST 2019]; root of context hierarchy
Playing sgt. pepper's lonely hearts club band by the beatles
Jun 19, 2019 9:35:10 PM org.springframework.context.support.GenericApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@4590c9c3: startup date [Wed Jun 19 21:35:10 CST 2019]; root of context hierarchy Process finished with exit code 0
4:接下来通过给bean添加注解来实现自动装配:
再创建一个bean,这个bean需要用到上面创建的compactDisc类(依赖这个类):
package com.springinaction.cn; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd){
this.cd = cd;
} public void play(){
cd.play();
}
}
再次测试一下:
package com.springinaction.cn; 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 CompactDisc cd; @Test
public void cdShouldNotBeNull(){
cd.play();
} @Autowired
private CDPlayer player;
@Test
public void play(){
player.play();
} }
测试结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/bin/java -ea -Didea.test.cyclic.buffer.size=10485760 "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=64301:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit-rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit5-rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/lib/tools.jar:/Users/zhenghongbo/IdeaProjects/BeanWiring/target/test-classes:/Users/zhenghongbo/IdeaProjects/BeanWiring/target/classes:/Users/zhenghongbo/Documents/apache-maven-local-repo/junit/junit/4.12/junit-4.12.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-aop/4.3.1.RELEASE/spring-aop-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-beans/4.3.1.RELEASE/spring-beans-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-core/4.3.1.RELEASE/spring-core-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-context/4.3.1.RELEASE/spring-context-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-expression/4.3.1.RELEASE/spring-expression-4.3.1.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-test/4.3.5.RELEASE/spring-test-4.3.5.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-jdbc/4.3.5.RELEASE/spring-jdbc-4.3.5.RELEASE.jar:/Users/zhenghongbo/Documents/apache-maven-local-repo/org/springframework/spring-tx/4.3.5.RELEASE/spring-tx-4.3.5.RELEASE.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.springinaction.cn.CDPlayerTest,play
Jun 19, 2019 10:02:30 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
Jun 19, 2019 10:02:30 PM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
Jun 19, 2019 10:02:30 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@2812cbfa, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2acf57e3, org.springframework.test.context.support.DirtiesContextTestExecutionListener@506e6d5e, org.springframework.test.context.transaction.TransactionalTestExecutionListener@96532d6, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@3796751b]
Jun 19, 2019 10:02:30 PM org.springframework.context.support.GenericApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@32e6e9c3: startup date [Wed Jun 19 22:02:30 CST 2019]; root of context hierarchy
Playing sgt. pepper's lonely hearts club band by the beatles Process finished with exit code 0
代码结构:
注解总结:
@Component 使用在类上,表示该类是一个组件类,spring容器将为这个类创建bean,@Component注解常用的属性是设置bean的id:@Component("lonelyHeartsClub"),可以使用@Named注解代替@Component注解;
@Configuration表明该类是一个配置类(用来代替spring的xml形式的配置文件);
@ComponentScan该注解用于在spring中启用组件扫描,该注解最常用的属性是basePackages,例如:@ComponentScan(basePackages={"soundsystem", "video"})这种方式指定扫描基础包,另一种类型安全的指定基础扫描包的方式是使用basePackagesClasses,例如@ComponentScan(basePackagesClasses={CDPlayer.class, DVDPlayer.class}),这些类所在的包将成为扫描的基础包;
@Autowired注解用于实现自动装配,spring将在应用上下文中查找需要注入的bean,@Autowired注解可以用在类的任何方法上(构造器、Setter)或者是用在属性上;@Autowired是spring的注解,可以用@Inject注解代替;
二、使用java代码显式装配bean:
既然是使用显式配置,则需要将上面的代码中的组件扫描注解移除掉:
package com.springinaction.cn; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
public class CDPlayerConfig {
}
这时候如果再次运行测试,会直接失败:
SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2acf57e3] to prepare test instance [com.springinaction.cn.CDPlayerTest@7c0c77c7]
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.springinaction.cn.CDPlayerTest': Unsatisfied dependency expressed through field 'cd': No qualifying bean of type [com.springinaction.cn.CompactDisc] found for dependency [com.springinaction.cn.CompactDisc]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.cn.CompactDisc] found for dependency [com.springinaction.cn.CompactDisc]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
。。。
此时需要在JavaConfig中显示声明Bean并组装Bean:
package com.springinaction.cn; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
public class CDPlayerConfig { @Bean(name = "lonelyHeartsClubBand")
public CompactDisc sgtPeppers(){
return new SgtPeppers();
} @Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
}
再次运行测试程序,测试通过:
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
Jun 19, 2019 10:42:32 PM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
Jun 19, 2019 10:42:32 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@2812cbfa, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2acf57e3, org.springframework.test.context.support.DirtiesContextTestExecutionListener@506e6d5e, org.springframework.test.context.transaction.TransactionalTestExecutionListener@96532d6, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@3796751b]
Jun 19, 2019 10:42:32 PM org.springframework.context.support.GenericApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@32e6e9c3: startup date [Wed Jun 19 22:42:32 CST 2019]; root of context hierarchy
Playing sgt. pepper's lonely hearts club band by the beatles Process finished with exit code 0
注解总结:
@Bean注解:带有Bean注解的方法用于产生Bean的实例,@Bean注解可使用name属性指定别名。与@Bean注解配合使用的注解包括@Scope注解(singleton单例模式(spring默认),prototype多例,request、session、global session作用域)
三、使用XML装配Bean
(一)使用构造器注入
1:在xml中声明一个Bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/> </beans>
与JavaConfig不同的是,使用XML声明Bean不需要显式创建SgtPeppers的实例了,spirng发现这个Bean元素时,会调用SgtPeppers的默认构造函数来创建Bean。另外注意,Bean的类型声明是放在字符串中的,这是类型不安全的,无法在编译期的类型检查过程中发现字符串拼写错误。
2:将SgtPeppers注入到CDPlayer中(注入初始化Bean):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/> <bean id="cdPlayer" class="com.springinaction.cn.CDPlayer" c:cd-ref="compactDisc"/> </beans>
上面的代码中使用了c命名空间来声明构造器参数。
DI依赖注入除了类之间的装配,还有需要将基本的字面值来配置对象(将字面量注入到构造器中),示例如下:
- 创建一个新的类BlankDisc,这个类有个构造函数接受两个字面量:
package com.springinaction.cn; public class BlankDisc implements CompactDisc {
private String title;
private String artist;
public BlankDisc(String title, String artist){
this.title = title;
this.artist = artist;
}
public void play(){
System.out.println("Playing " + title + " by " + artist);
}
}
- 在XML文件中装配这个Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--
<bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/>
-->
<bean id="compactDisc" class="com.springinaction.cn.BlankDisc">
<constructor-arg value="Sgt Peppers Lonely Hearts Club Band"/>
<constructor-arg value="The Beatles"/>
</bean> <bean id="cdPlayer" class="com.springinaction.cn.CDPlayer" c:cd-ref="compactDisc"/> </beans>
如果类的构造方法参数中有List类型的参数时,XML配置方法如下:
类:
package com.springinaction.cn; import java.util.List; public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks; public BlankDisc(String title, String artist){
this.title = title;
this.artist = artist;
} public BlankDisc(String title, String artist, List<String> tracks){
this.title = title;
this.artist = artist;
this.tracks = tracks;
} public void play(){
System.out.println("Playing " + title + " by " + artist);
}
}
XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--
<bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/>
-->
<bean id="compactDisc" class="com.springinaction.cn.BlankDisc">
<constructor-arg value="Sgt Peppers Lonely Hearts Club Band"/>
<constructor-arg value="The Beatles"/>
<constructor-arg>
<list>
<value>Sgt Peppers Lonely Hearts Club Band</value>
<value>With a Little Help From My Friends</value>
<value>Lucy In The Sky With Diamonds</value>
</list>
</constructor-arg>
</bean> <bean id="cdPlayer" class="com.springinaction.cn.CDPlayer" c:cd-ref="compactDisc"/> </beans>
(二)使用属性注入
类:
package com.springinaction.cn; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer {
private CompactDisc compactDisc;
@Autowired
public void setCompactDisc(CompactDisc compactDisc){
this.compactDisc = compactDisc;
} public void play(){
compactDisc.play();
}
}
这时候既可以选择构造器注入,也可以使用属性注入,通常的规则是:对于强依赖,使用构造器注入,对于可选的属性使用属性注入。
XML配置(使用P命名空间代替property元素):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--
<bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/>
-->
<bean id="compactDisc" class="com.springinaction.cn.BlankDisc">
<constructor-arg value="Sgt Peppers Lonely Hearts Club Band"/>
<constructor-arg value="The Beatles"/>
<constructor-arg>
<list>
<value>Sgt Peppers Lonely Hearts Club Band</value>
<value>With a Little Help From My Friends</value>
<value>Lucy In The Sky With Diamonds</value>
</list>
</constructor-arg>
</bean> <bean id="cdPlayer" class="com.springinaction.cn.CDPlayer" p:compactDisc-ref="compactDisc"/> </beans>
将字面量注入到属性的方法与构造器注入字面量方式类似,示例如下:
类:
package com.springinaction.cn; import java.util.List; public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks; public void setTitle(String title) {
this.title = title;
} public void setArtist(String artist) {
this.artist = artist;
} public void setTracks(List<String> tracks) {
this.tracks = tracks;
} public void play(){
System.out.println("Playing " + title + " by " + artist);
}
}
XML配置(使用p命名空间):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--
<bean id="compactDisc" class="com.springinaction.cn.SgtPeppers"/>
-->
<bean id="compactDisc" class="com.springinaction.cn.BlankDisc"
p:title="Sgt Peppers Lonely Heart Club Band"
p:artist="The Beatles">
<property name="tracks">
<list>
<value>Sgt Peppers Lonely Heart Club Band</value>
<value>Lucy In The Sky With Diamonds</value>
<!-- ... more-->
</list>
</property>
</bean> <bean id="cdPlayer" class="com.springinaction.cn.CDPlayer" p:compactDisc-ref="compactDisc"/> </beans>
四、使用混合装配
(一)多个JavaConfig类进行配置:
- 在每个配置类上使用@Configuration注解;
- 在其中一个配置类上使用@Import(AnotherJavaConfigClass.class)即可实现导入;
【也可以在一个统一的JavaConfig类上使用@Import注解导入其他的所有JAVA配置类:@Import(AnotherJavaConfigClass.class, SomeElseJavaConfigClass.class)】
(二)在JavaConfig类中导入在XML中配置的Bean:
- 在Java配置类上增加一个@ImportResource注解:@ImportResource("classpath:cd-config.xml")
(三)在XML中导入另一个XML配置文件:
- 在目标XML文件中使用<import>元素:<import resource="cd-config.xml"
(四)没有一个直接的方法能将JavaConfig类导入到xml文件,间接的,通过声明一个配置累的Bean来导入:
<Bean class="soundsystem.CDConfig.class" />
注:此文参照 中国工信出版社的《Spring实战》第四版 一书整理,仅供个人学习记录。
spring装配bean的三种方式及其混合装配的更多相关文章
- spring创建bean的三种方式
spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...
- spring 装配bean的三种方式
这段时间在学习Spring,依赖注入DI和面向切面编程AOP是Spring框架最核心的部分.这次主要是总结依赖注入的bean的装配方式. 什么是依赖注入呢?也可以称为控制反转,简单的来说,一般完成稍微 ...
- Spring容器装配Bean的三种方式
欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...
- Spring实战(三)Spring中装配Bean的三种方式---XML、JavaConfig、AutoWire
创建应用对象之间协作关系的行为称为装配(wiring),这也是依赖注入的本质. Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而开发者需要告诉Spring需要创建哪些 ...
- Spring装配Bean的三种方式+导入和混合配置
目录 Spring IoC与bean 基于XML的显式装配 xml配置的基本结构 bean实例的三种创建方式 依赖注入的两种方式 构造器注入方式 setter方法注入方式 利用命名空间简化xml 基于 ...
- 装配Bean的三种方式
一.装配Bean就是在xml写一个Bean标签:装配完Bean,还需要读取xml配置文件创建Spring容器来创建对象: 1.new 实现类方式 正常的三种创建Bean容器的方法都可以根据装配的Bea ...
- Spring 实例化bean的三种方式
第一种方法:直接配置Bean <bena id="所需要实例化的一个实例名称" class="包名.类名"/> 例如: 配置文件中的bean.XML ...
- Spring实例化Bean的三种方式及Bean的类型
1.使用类构造器实例化 [默认的类构造器] <bean id=“orderService" class="cn.itcast.OrderServiceBean"/ ...
- spring实例化bean的三种方式
公共使用的实体
随机推荐
- 前端构建工具gulp超详细配置, 使用教程(图文)
流程 1. 输入命令(可以使用git bash或者命令控制台cmd) npm install -g gulp 安装全局gulp命令 2. 创建一个项目文件夹, 当前项目文件夹下输入命令npm init ...
- Excel的查询函数vlookup和index使用
需求 有一些省市的区县,有600多条数据,只有名称,没有编码.现在要根据名称去3000多条数据里面查询. 如图,拿出一部分数据来演示 vlookup 使用vlookup,由于vlookup只能查询数据 ...
- Koa微信公众号开发
微信开发者模式开启需要服务器域名合法并且把接口配置好,这个接口是接通的关键,接通后微信后台的菜单设置功能,客服功能会失效,需要开发者自定义菜单和智能客服界面,并且接通后可以调用微信网页内部的定位分享等 ...
- leetcode349 350 Intersection of Two Arrays & II
""" Intersection of Two Arrays Given two arrays, write a function to compute their in ...
- leetcode102 Binary Tree Level Order Traversal
""" Given a binary tree, return the level order traversal of its nodes' values. (ie, ...
- java正则表达式校验密码必须是包含大小写字母、数字、特殊符号的8位以上组合
一.需求:密码必须是包含大写字母.小写字母.数字.特殊符号(不是字母,数字,下划线,汉字的字符)的8位以上组合 二.方案:利用正则表达式来校验 三.思路:排除法 1.排除大写字母.小写字母.数字.特殊 ...
- 电脑必须用U盘引导盘才能进系统解决办法
昨天为了装Ubuntu双系统把系统给装崩了,结果重装win7系统之后出现了以下问题,百度的结果有些杂乱,解决过程自己做一下记录. 问题一:安装程序结束后,出现“Windows安装程序无法将Window ...
- POJ 1458:Common Subsequence
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 41957 Accepted: 16 ...
- 一次C语言编程遇到的问题总结
今天用C语言做了一个简单的用户登录注册存取款等功能的系统,发现有很多功能并不会实现,大概是使用Java太多了导致许多C的知识都忘记了,现在把碰到的问题总结如下: 1.字符串复制问题 java等一些编程 ...
- 【转】美团 MySQL 数据实时同步到 Hive 的架构与实践
文章转载自公众号 美团技术团队 , 作者 萌萌 背景 在数据仓库建模中,未经任何加工处理的原始业务层数据,我们称之为ODS(Operational Data Store)数据.在互联网企业中,常见的 ...