6.装配Bean
装配方案
- 基于xml
- 基于java
- 基于隐式地bean发现与自动装配
通过自动化装配
-
优点
便利,自动化,可以解决大部分问题
-
Spring从两个角度来实现自动转配
-
组件扫描(component scan)
-
xml
<context:component-scan base-package="com.desmond"/>
-
@component
-
-
自动装配(autowiring)
-
-
@ComponentScan 默认扫描与该配置类相同的基础包,i.e. @ComponentScan配置在那个package的类下面,就扫描该package.
-
@ComponentScan可以指定多个扫描路径
-
@ComponentScan可以使用 Class或者字符串路径 来指定base package路径:class路径:
扫描二维码关注公众号,回复: 3652267 查看本文章@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代码装配
-
相比XML, 对重构更加友好,更加安全(Class类比xml 字符串更不容出错),类型安全。
-
可以自定义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; } }
-
当度配置Java config包,已使他与业务代码隔离
通过XML装配
- 最成熟、功能最强大
- 基于constructor初始化
- 基于setter初始化
导入和混合装配
-
Java config 组合其他config
-
一个 @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,则后方会覆盖前者
-
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 { }
-
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
-