6.装配Bean

6.装配Bean

装配方案

  1. 基于xml
  2. 基于java
  3. 基于隐式地bean发现与自动装配

通过自动化装配

  1. 优点

    1. 便利,自动化,可以解决大部分问题
  2. Spring从两个角度来实现自动转配

    1. 组件扫描(component scan)

      1. xml

        <context:component-scan base-package="com.desmond"/>
        
      2. @component

    2. 自动装配(autowiring)

  3. @ComponentScan 默认扫描与该配置类相同的基础包,i.e. @ComponentScan配置在那个package的类下面,就扫描该package.

  4. @ComponentScan可以指定多个扫描路径

  5. @ComponentScan可以使用 Class或者字符串路径 来指定base package路径:class路径:

    @Configuration
    @ComponentScan(basePackageClasses = com.desmond.springlearning.scan.Human.class)
    public class Man {
        @Autowired
        private Human human;
    
        public void sayHi() {
            human.sayHi();
        }
    }
    

    或者 字符串路径:

    @ComponentScan(basePackages = "com.desmond.springlearning.scan")
    

    或者 两者组合:

    @Configuration
    @ComponentScans({
            @ComponentScan(basePackageClasses = com.desmond.springlearning.scan.Human.class),
            @ComponentScan(basePackages = "com.desmond.springlearning.scan")
    })
    

    Class 路径比字符路径更安全(字符串路径可能会出错,尽快有IDE的辅助检查),对重构也更加友好,可以创建一个接口,只是用来指定base package即可。

通过Java代码装配

  1. 相比XML, 对重构更加友好,更加安全(Class类比xml 字符串更不容出错),类型安全。

  2. 可以自定义bean的实例化,e.g.

    @Configuration
    public class Db1Configuration {
        @Bean
        public DbConnection connection() {
            DbConnection conn = new DbConnection("con1")
            // 可以自定义一大堆逻辑
           
            return new DbConnection("con1");
        }
    }
    

    而简单的xml 不具体这样的自定义功能:

    <bean class="com.desmond.springlearning.scan.mixed.DbConnection"/>
    

    ,但是可以通过factory-method来达到同样的目的

    <bean id="fb" class="com.desmond.springlearning.scan.mixed.DbConnectionFactory"/>
    <bean id="factoryConn" factory-bean="fb" factory-method="createDbConnection"/>
    
    public class DbConnectionFactory {
        public DbConnection createDbConnection() {
            DbConnection connection = new DbConnection();
            connection.setName("from factory.");
    
            // other logic
    
            return connection;
        }
    }
    
  3. 当度配置Java config包,已使他与业务代码隔离

通过XML装配

  1. 最成熟、功能最强大
  2. 基于constructor初始化
  3. 基于setter初始化

导入和混合装配

  1. Java config 组合其他config

    1. 一个 @Configuration相当于一个xml 配置文件,可以导入其他xml:

      @Configuration
      public class Db1Configuration {
          @Bean
          public DbConnection connection() {
              return new DbConnection("con1");
          }
      }
      
      public class Db2Configuration {
          @Bean
          public DbConnection connection() {
              return new DbConnection("con2");
          }
      }
      
      
      @Configuration
      @Import({Db2Configuration.class, Db1Configuration.class})
      public interface CombinationConfiguration {
      }
      
      public class Test {
          public static void main(String[] args) {
              ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CombinationConfiguration.class);
      
              DbConnection connection = (DbConnection)applicationContext.getBean("connection");
              connection.sayHi();
          }
      

      如果 Db1Configuration、Db2Configuration有同名的bean,则后方会覆盖前者

    2. java config引入xml配置
      xml

      <bean id="conn2" class="com.desmond.springlearning.scan.mixed.DbConnection" p:name="I'm db2 from xml."/>
      

      Configuration:

      @Configuration
      @Import(Db1Configuration.class)
      @ImportResource("classpath:scan/db2Connection.xml")
      public class CombinationWithXml {
      }
      
    3. xml中引入java config

      java

      package com.desmond.springlearning.scan.mixed;
      
      import com.desmond.springlearning.scan.Human;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      /**
       * @author presleyli
       * @date 2018/9/26 上午6:45
       */
      @Configuration
      public class Db1Configuration {
          @Bean(name = "conn1")
          public DbConnection connection() {
              return new DbConnection("conn1");
          }
      }
      
      

      db2Connection.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:p="http://www.springframework.org/schema/p"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"
              default-autowire="default">
      
          <bean id="conn2" class="com.desmond.springlearning.scan.mixed.DbConnection" p:name="conn2"/>
      
      
      </beans>
      

      Xmlcomb.xml, 注意开启注解驱动:<context:annotation-config/>

      <?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 "
             default-autowire="default">
      
          <context:annotation-config/>
      
          <bean class="com.desmond.springlearning.scan.mixed.Db1Configuration"/>
      
          <import resource="db2Connection.xml"/>
      
      </beans>	
      

      测试类

      package com.desmond.springlearning.scan.mixed;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      /**
       * @author presleyli
       * @date 2018/9/26 上午6:49
       */
      public class TestJavaFromXml {
          public static void main(String[] args) {
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scan/xmlcomb.xml");
      
              DbConnection connection = (DbConnection)applicationContext.getBean("conn1");
              connection.sayHi();
      
              connection = (DbConnection)applicationContext.getBean("conn2");
              connection.sayHi();
          }
      }
      
      

      结果:

      objc[14480]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java (0x1017fd4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1018814e0). One of the two will be used. Which one is undefined.
      九月 26, 2018 7:52:44 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
      信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1a86f2f1: startup date [Wed Sep 26 07:52:44 CST 2018]; root of context hierarchy
      九月 26, 2018 7:52:45 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
      信息: Loading XML bean definitions from class path resource [scan/xmlcomb.xml]
      九月 26, 2018 7:52:45 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
      信息: Loading XML bean definitions from class path resource [scan/db2Connection.xml]
      
      I'm conn1
      I'm conn2
      

猜你喜欢

转载自blog.csdn.net/firemaple_li/article/details/82847923