1. 在Spring中,对象无需自己查找或创建与其所关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。
2. 创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。
3.Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。
4. 三种主要的装配机制:
在XML中进行显式配置。
在Java中进行显式配置。
隐式的bean发现机制和自动装配。
5. Spring从两个角度来实现自动化装配:
组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
自动装配(autowiring):Spring自动满足bean之间的依赖。
6. @component注解:这个简单的注解表明该类会作为组件类,并告知Spring要为这个类创建
bean
7. 不过,组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。
@ComponentScan:这个注解能够在Spring中启用组件扫描。
如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包。因为CDPlayerConfig类位于soundsystem包中,因此Spring将会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类。这样的话,就能发现CompactDisc,并且会在Spring中自动为其创建一个bean。
8. 为组件扫描的bean命名:
(1) Spring应用上下文中所有的bean都会给定一个ID。在前面的例子中,尽管我们没有明确地为SgtPeppersbean设置ID,但Spring会根据类名为其指定一个ID。具体来讲,这个bean所给定的ID为sgtPeppers,也就是将类名的第一个字母变为小写。
(2) 如果想为这个bean设置不同的ID,你所要做的就是将期望的ID作为值传递给@Component注解。比如说,如果想将这个bean标识为lonelyHeartsClub,那么你需要将SgtPeppers类的@Component注解配置为如下所示:
1 @Component("lonelyHeartsClub")
(3) 还有另外一种为bean命名的方式,这种方式不使用@Component注解,而是使用Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解来为bean设置ID:
1 @Named("lonelyHeartsClub")
9. 设置组件扫描的基础包
(1)默认基础包:
到现在为止,我们没有为@ComponentScan设置任何属性。这意味着,按照默认规则,它会以配置类所在的包作为基础包(basepackage)来扫描组件。
(2) 指定基础包
为了指定不同的基础包,你所需要做的就是在@ComponentScan的value属性中指明包的名称:
@ComponentScan(basePackages="soundsystem")
指定多个基础包:
@ComponentScan(basePackages={"soundsystem",“video”})
指定基础包为包中所包含的类或接口(更安全):
@ComponentScan(basePackageclasses={"CDPlayer.class",“DVDPlayer.class”})这些类所在的包将作为组件扫描的基础包
10.通过为bean添加注解实现自动装配----将组件扫描得到的bean和它们的依赖装配在一起
自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。
@Autowired注解:
(1) 用在构造器上
(2)用在属性的Setters方法上
(3)类的任意方法上
@Inject注解来源于Java依赖注入规范,该规范同时还为我们定义了@Named注解。
12.显示配置(一)---通过Java代码装配bean
将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配。
(1) 创建配置类
@Configuration注解 表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
(2) 声明简单的bean
要在JavaConfig中声明bean,我们需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。
1 @Bean 2 public CompactDisc sgtPeppers(){ 3 return new SgtPeppers(); 4 }
@Bean注解 会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。
bean的ID指定:
1) 默认情况下:bean的ID与带有@Bean注解的方法名是一样的
2) 具体指定:如果你想为其设置成一个不同的名字的话,那么可以重命名该方法,也可以通过name属性指定一个不同的名字
@Bean(name="lonelyHeartsClubBand")
(3) 借助JavaConfig实现注入
同样使用了@Bean注解,这表明这个方法会创建一个bean实例并将其注册到Spring应用上下文中
1 @Bean 2 public CDPlayer cdPlayer(){ 3 4 return new CDPlayer(sgtPeppers()); 5 }
CompactDisc是通过调用sgtPeppers()得到的,但情况并非完全如此。因为sgtPeppers()方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。【理解】所以其他的cdplayer得到的其实同一个CD
更好的方式是:
1 @Bean 2 public CDPlayer cdPlayer(CompactDisc compactDisc){ 3 return new CDPlayer(compactDisc); 4 }
上面都是使用构造器风格来实现DI,我们也可以通过Setters方法注入CompactDisc:
1 @Bean 2 public CDPlayer cdPlayer( CompactDisc compactDisc){ 3 CDPlayer cdPlayer = new CDPlayer(compactDisc); 4 cdPlayer.setCompactDisc(compactDisc); 5 return cdPlayer; 6 }
13. 显式配置(二)-----通过XML配置bean(实际应用中不建议)
在使用JavaConfig的时候,这意味着要创建一个带有@Configuration注解的类,而在XML配置中,这意味着要创建一个XML文件,并且要以<beans>元素为根。
最简单的Spring XML配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context"> 7 8 </beans>
(1) 声明一个简单的<bean>
<bean class = "soundsystem.SgtPeppers" />
这里声明了一个很简单的bean,创建这个bean的类通过class属性来指定的,并且要使用全限定的类名。
通常来讲更好的办法是借助id属性,为每个bean设置一个你自己选择的名字:
<bean id="compactDisc" class="soundsystem.SgtPeppers">
(2)借助构造器注入初始化bean
在XML中声明DI时,会有多种可选的配置方案和风格。具体到构造器注入,有两种基本的配置方案可供选择:
. <constructor-arg>元素
. 使用Spring 3.0所引入的c-命名空间
类一:装配引用
1) <constructor-arg>元素
<bean id = "cdPlayer" class="soundsystem.CDPlayer">
<constructer-arg ref="compactDisc" />
</bean>
当Spring遇到这个<bean>元素时,它会创建一个CDPlayer实例。<constructor-arg>元素会告知Spring要将一个ID
为compactDisc的bean引用传递到CDPlayer的构造器中。
2) 使用Spring 3.0所引入的c-命名空间
其XML文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context"> 7 8 </beans>
完成注入的相关代码:
<bean id="cdPlayer" class="soundsystem.CDPlayer"
c: cd-ref="compactDisc" /> //cd:指的是构造器的参数名
类二:装入字面值
类三: 装配集合<list>(c命名无法装配集合)
<value></value>
<value></value>
</list>
(3) 设置属性---Spring XML实现属性注入
(一) 在JavaConfig中引入XML配置
1) 在配置类的基础上将另一个配置类组合在一起@Import
@Configuration
@Import(CDConfig.class)
2) 可以创建一个更高级别的配置类,利用@Import将两个子配置类组合在一起
@Import(CDPlayerConfig.class,CDConfig.class)
3) 完全重新创建一个配置类,@ImportResources注解:可以让Spring同时加载基于XML的配置和其他基于Java的配置
@Configuration //注解下面的类是一个配置类
@Import(CDPlayerConfig.class)
@InportResource("classpath:cd-config.xml")
(二)在XML配置中引用JavaConfig----@import注解