spring裝配bean的三種方式及其混合裝配

在spring容器中裝配bean有三種基本方式和混合裝配方式:html

  • 隱式的bean自動發現機制和自動裝配
  • 在java中進行顯式配置
  • 在xml中配置
  • 混合裝配(在多個java文件中配置、在JavaConfig中引用XML配置、在XML中引用JavaConfig配置)

1、使用自動化方式裝配bean示例:java

1:建立maven項目並引入依賴:web

<?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>
View Code

2:建立簡單java類接口及其實現,並將其實現類增長@Component註解,spring容器將爲這個類建立bean:spring

package com.springinaction.cn;

public interface CompactDisc {
    public void play();
}
View Code
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);
    }
}
View Code

3:建立配置類,啓用組件掃描:express

package com.springinaction.cn;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {
}
View Code

 

至此,可被被spring自動裝配的bean已經建立好了,用junit測試一下:apache

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();
    }

}
View Code

運行結果:安全

/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
View Code

4:接下來經過給bean添加註解來實現自動裝配:session

再建立一個bean,這個bean須要用到上面建立的compactDisc類(依賴這個類):app

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();
    }
}
View Code

再次測試一下:maven

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();
    }

}
View Code

測試結果:

/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
View Code

代碼結構:

註解總結:

@Component 使用在類上,表示該類是一個組件類,spring容器將爲這個類建立bean,@Component註解經常使用的屬性是設置bean的id:@Component("lonelyHeartsClub"),可使用@Named註解代替@Component註解;

@Configuration代表該類是一個配置類(用來代替spring的xml形式的配置文件);

@ComponentScan該註解用於在spring中啓用組件掃描,該註解最經常使用的屬性是basePackages,例如:@ComponentScanbasePackages={"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 {
}
View Code

這時候若是再次運行測試,會直接失敗:

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)
。。。
View Code

此時須要在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);
    }
}
View Code

再次運行測試程序,測試經過:

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
View Code

註解總結:

@Bean註解:帶有Bean註解的方法用於產生Bean的實例,@Bean註解可以使用name屬性指定別名。與@Bean註解配合使用的註解包括@Scope註解(singleton單例模式(spring默認),prototype多例,request、session、global session做用域)

 

3、使用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>
View Code

與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>
View Code

上面的代碼中使用了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);
    }
}
View Code
  • 在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>
View Code

 

若是類的構造方法參數中有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);
    }
}
View Code

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>
View Code

(二)使用屬性注入

類:

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();
    }
}
View Code

這時候既能夠選擇構造器注入,也可使用屬性注入,一般的規則是:對於強依賴,使用構造器注入,對於可選的屬性使用屬性注入。

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>
View Code

將字面量注入到屬性的方法與構造器注入字面量方式相似,示例以下:

類:

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);
    }
}
View Code

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>
View Code

 

4、使用混合裝配

(一)多個JavaConfig類進行配置:

  1. 在每一個配置類上使用@Configuration註解;
  2. 在其中一個配置類上使用@Import(AnotherJavaConfigClass.class)便可實現導入;

【也能夠在一個統一的JavaConfig類上使用@Import註解導入其餘的全部JAVA配置類:@Import(AnotherJavaConfigClass.class, SomeElseJavaConfigClass.class)】

(二)在JavaConfig類中導入在XML中配置的Bean:

  1. 在Java配置類上增長一個@ImportResource註解:@ImportResource("classpath:cd-config.xml")

(三)在XML中導入另外一個XML配置文件:

  1. 在目標XML文件中使用<import>元素:<import resource="cd-config.xml"

(四)沒有一個直接的方法能將JavaConfig類導入到xml文件,間接的,經過聲明一個配置累的Bean來導入:

<Bean class="soundsystem.CDConfig.class" />

 

注:此文參照 中國工信出版社的《Spring實戰》第四版 一書整理,僅供我的學習記錄。

相關文章
相關標籤/搜索