第2章—装配Bean—自动化装配Bean
自动化装配Bean
2.1.Spring配置可选方案
装配是依赖注入DI的本质,Spring提供了以下三种注入的装配机制:
- 在XMl中进行显式配置
- 在java中进行显式配置
- 隐式的Bean发现机制和自动装配
2.2.自动化装配Bean
Spring从两个角度来实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现用用上下文中所创建的Bean.
- 自动装配(autowiring):Spring自动满足bean之间的依赖.
实例:
CD和CDPlayer,如果你不将CD放入(注入)到播放器中,那么CD播放器其实是没多大用处的,所以说,CD播放器是依赖于CD才能完成它的使命.
package com.CDDemo;
//CD的接口
public interface CompactDisc {
public void play();
}
package com.CDDemo;
import org.springframework.stereotype.Component;
//CD的实现类 歌曲
@Component
public class SgtPeppers implements CompactDisc {
private String title = "sgt";
private String song = "Twinkle, twinkle, little start";
public void play() {
System.out.println("title:" + title + "song:" + song);
}
}
package com.CDDemo;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//播放器的设置
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
package com.CDDemo;
//测试类
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;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDTest {
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
cd.play();
}
}
上面需要注意的是:
@Configuration
定义了Spring的装配规则
@ComponentScan
这个会默认扫描与配置类相同的包.(这里扫描package com.CDDemo;同包以及下面的所有的子包)
查找出带有@Component注解的类 这样就能发现CompactDisc(因为注解了它的实例) 并为它在Spring中创建一个Bean.
当然你也可以通过配置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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--扫描包的配置-->
<context:component-scan base-package="com.CDDemo"/>
</beans>
2.2.1.为组件扫描的Bean命名
通过Spring的注解可以让Spring给注入的Bean一个ID,这个ID默认为类名(首字母小写);
当然你也可以通过命名来明确给这个类注入的时候带有什么名称的ID;
1.@Componment("test_SgtPeppers")
2.@Name("test_SgtPeppers")
当然我们一般情况下直接用@Componment使用ID默认为类名(首字母小写)就可以了,因为这样用起来比较整洁,特殊情况可以在@Componment()的括号中加入指定ID名称.
2.2.2.设置组件扫描的基础包
在上面的@ComponentScan默认扫描注解类所在的包,那么有没有一种方式能够更为精准有效的扫描我们所需要的包呢?在Spring中有如下几种方式可供选择:
1.在ComponentScan的Value中直接指明包的名称
//在ComponentScan中直接指明包的名称
@ComponentScan("com.CDDemo")
public class CDPlayerConfig {
}
2.在ComponentScan中basePackages的直接指明包的名称 是复数 可以指定扫描多个包
@ComponentScan(basePackages = "com.CDDemo")
public class CDPlayerConfig {
}
@ComponentScan(basePackages = {"com.CDDemo","com.aop"})
public class CDPlayerConfig {
}
3.在ComponentScan中的basePackageClasses加入扫描的类名(会自动扫描类所在的包)
@ComponentScan(basePackageClasses = {SgtPeppers.class,CDTest.class})
public class CDPlayerConfig {
}
2.2.3.通过为Bean添加注解实现自动装配
在Spring中还有种方便而且应用广泛的方法,在需要依赖注入的地方加上@Autowired,这个表明当Spring创建CompactDisc Bean的时候,会通过这个传入该接口的实例类的Bean.
public class CDTest {
@Autowired
private CompactDisc cd;
}
@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上,(但是虽然用在Getter方法上不报错,但没有实际意义, 请看下文的解释)
@Autowired
public void setTitle(String title) {
this.title = title;
}
先看一下bean实例化和@Autowired装配过程:
- 一切都是从bean工厂的getBean方法开始的,一旦该方法调用总会返回一个bean实例,无论当前是否存在,不存在就实例化一个并装配,否则直接返回。(Spring MVC是在什么时候开始执行bean的实例化过程的呢?其实就在组件扫描完成之后)
- 实例化和装配过程中会多次递归调用getBean方法来解决类之间的依赖。
- Spring几乎考虑了所有可能性,所以方法特别复杂但完整有条理。
- @Autowired最终是根据类型来查找和装配元素的,但是我们设置了
<beans default-autowire="byName"/>
后会影响最终的类型匹配查找。因为在前面有根据BeanDefinition的autowire类型设置PropertyValue值得一步,其中会有新实例的创建和注册。就是那个autowireByName方法。
另外@Autowired注解还可以用在方法上面,能和Setter方法上使用该注解发挥相同的作用
@Autowired
public void insertDisc() {
System.out.println("注解在方法名上");
}
以上方法都是有匹配的Bean的情况下有效的,那如果找不到匹配的Bean的话,Spring会抛出一个异常.为了避免出现这种异常,你可以将@Autowired的require属性设置为false,但还是建议根据实际情况找到相应的问题并解决:
@Autowired(required = false)
public void insertDisc() {
System.out.println("注解在方法名上");
}
但是把required改为false需谨慎,如果在你的代码中没有进行null检查的话,这个处于未装配状态的属性随时可能出现NullPointerException.
但你不想在代码中导出使用@Autowired的时候可以考虑用@Inject替换,但这两个之间有些许差别,一般可以相互替换.
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class SgtPeppers implements CompactDisc {
private String title = "sgt";
private String song = "Twinkle, twinkle, little start";
public void play() {
System.out.println("title:" + title + "song:" + song);
}
@Inject
public void insertDisc() {
System.out.println("注解在方法名上");
}
}
请注意:
1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。
2、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;
3、@Inject可以作用在变量、setter方法、构造函数上。
第2章—装配Bean—自动化装配Bean的更多相关文章
- Spring温故而知新 - bean的装配
Spring装配机制 Spring提供了三种主要的装配机制: 1:通过XML进行显示配置 2:通过Java代码显示配置 3:自动化装配 自动化装配 Spring中IOC容器分两个步骤来完成自动化装配: ...
- Spring温故而知新 – bean的装配
Spring装配机制 Spring提供了三种主要的装配机制: 1:通过XML进行显示配置 2:通过Java代码显示配置 3:自动化装配 自动化装配 Spring中IOC容器分两个步骤来完成自动化装配: ...
- Spring Bean 的装配方式
Spring Bean 的装配方式 装配 Bean 的三种方式 一个程序中,许多功能模块都是由多个为了实现相同业务而相互协作的组件构成的.而代码之间的相互联系又势必会带来耦合.耦合是个具有两面性的概念 ...
- 《Spring实战》读书笔记——如何实现自动化装配
加我微信公众号,一起夯实Java基础,向着诗和远方出发吧~ 如果所有的装配工作都交给Spring来自动完成,减少人工的干预,是不是就能减少依赖关系配置带来的麻烦呢?认真做自己的事儿吧,装配交给Spri ...
- Spring学习系列(二) 自动化装配Bean
一.Spring装配-自动化装配 @Component和@ComponentScan 通过spring注解(@Component)来表明该类会作为组件类,并告知Spring要为这类创建bean,不过组 ...
- 【Spring 核心】装配Bean(一) 自动化装配
Spring从两个角度实现自动化装配:组件扫描 (Spring自动发现应用上下文中所创建的bean)自动装配(autowiring)自动满足bean之间的依赖 组件扫描: package test.s ...
- Spring基础篇——bean的自动化装配
上篇博文讲Spring的IOC容器时说道,虽然容器功能强大,但容器本身只是个空壳,需要我们主动放入装配对象,并告诉它对象之间的协作关系,然后容器才能按照我们的指示发挥它的魔力,完成装配bean的使命. ...
- Spring入门(二):自动化装配bean
Spring从两个角度来实现自动化装配: 组件扫描(component scanning):Spring会自动发现应用上下文中需要创建的bean. 自动装配(autowiring):Spring会自动 ...
- 自动化装配Bean
一.Spring装配-自动化装配 @Component和@ComponentScan 通过spring注解(@Component)来表明该类会作为组件类,并告知Spring要为这类创建bean,不过组 ...
随机推荐
- ZSTU4270 同源数 2017-03-22 14:34 82人阅读 评论(0) 收藏
4270: 同源数 Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1284 Solved: 224 Description 如果x和y的质因子集合完 ...
- ISE、vivado、QuartusII调用notepad++、UE汇总(整理)
我已经用惯了notepad++编写Verilog代码,很喜欢这款编辑器,功能真的非常强大.所以,当需要对vivado.ISE或quartus ii中的工程进行Verilog代码上的编写或修改时,只需双 ...
- Zend_Application 流程详解
本周没什么工作,zend 系统性的东西渐渐忘记,抽时间整理一下代码!Zend_Application 负责加载配置以及初始化资源,所以index.php 会有这行代码 /** Zend_Applica ...
- Low-level Thinking in High-level Shading Languages
因为要反汇编shader代码,所以google了数学函数_sat的知识,发现了一些高级着色语言的优化相关的问题.Low-level Thinking in High-level Shading Lan ...
- 8.使用Exists监控ZNode的三大Change事件
一. zookeeper是一个分布式的协调程序(所有程序都是通过订阅它来相互感知) 1. tcp(长链接) + watcher server ->client client ->ser ...
- Math类的三个方法比较: floor() ceil() round()
public class Test { public static void main(String[] args) { double d1 = 3.4, d2 = 3.6; //正数 double ...
- 第六章:shiro Realm相关对象
Shiro 中的 AuthenticationToken AuthenticationToken 用于收集用户提交的身份(如用户名)及凭据(如密码).Shiro会调用CredentialsMatche ...
- Postgresql fillfactor
一个表的填充因子(fillfactor)是一个介于 10 和 100 之间的百分数.100(完全填充)是默认值.如果指定了较小的填充因子,INSERT 操作仅按照填充因子指定的百分率填充表页.每个页上 ...
- 使用Eclipse切换TFS工作区
这个问题首先牵涉到两个概念: - Eclipse的工作区:Eclipse的工作区是运行Eclipse时需要连接的本地代码空间,默认情况下,在Eclipse中创建的项目都保存在Eclipse的工作区中 ...
- Solr相似度名词:VSM(Vector Space Model)向量空间模型
最近想学习下Lucene ,以前运行的Demo就感觉很神奇,什么原理呢,尤其是查找相似度最高的.最优的结果.索性就直接跳到这个问题看,很多资料都提到了VSM(Vector Space Model)即向 ...