spring实战第二章小记-装配bean
时间:2020/02/06
一.思想
1.创建应用对象之间协作关系的行为通常称为装配,这也是依赖注入(DI)的本质。
对于上面这句话的个人理解:当我们在new一个对象时如果传入了别的对象作为参数(这个对象可能是引用数据类型也可能是基本数据类型),这时两个对象之间就形成了一种依赖关系,由于这种依赖关系的存在,两个对象之间就是一种强耦合的关系,而通过依赖注入可以降低两个对象之间的耦合度,注意,不是消除,如果两个对象之间没有耦合关系,那两个对象就是完全没有关系的。
2.spring框架提供了三种主要的装配机制:
- 在XML中进行显式配置
- 在Java中进行显示配置
- 隐式的bean发现机制和自动装配
3.关于上面三种方式的优先级(作者的意思,你可以根据自己的喜爱选择):
隐式的bean发现机制和自动装配>在Java中进行显示配置>在XML中进行显示装配
4.spring从两个角度来实现自动化装配:
- 组件扫描:spring会自动发现应用上下文中所创建的bean。
- 自动装配:spring自动满足bean之间的依赖。
5.自动装配:自动装配就是让spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在spring应用上下文中寻找匹配某个bean需求的其他bean。
6.在进行显式配置时,JavaConfig是更好的方案,因为它更为强大、类型安全并且对重构友好。
7.默认情况下,spring中的bean都是单例的。
8.在XML中声明DI时,会有多种可选的配置方案和风格。具体到构造器注入,有两种基本的配置方案可供选择:
- <constructor-arg>元素
- 使用spring3.0所引入的c-命名空间
9.对于DI来说,有的时候是指类型的装配——也就是将对象的引用装配到依赖于它们的其他对象之中。而有的时候,我们需要做的只是用一个字面量来配置对象(基本类型对象以及String类型对象)。
10.在装配bean引用和字面量值方面,<constructor-arg>和c-命名空间的功能是相同的。但是c-命名空间无法将集合装配到构造器参数中。
11.该选择构造器注入还是属性注入(Setter方法注入)呢?作为一个通用的规则,对强依赖使用构造器注入,而对可选择的依赖使用属性注入。
12.spring框架的核心是spring容器,整个容器中存放的东西可以看作key-value对,key是bean的id,value是bean的对象。
二.在XML中进行显示装配
1.spring的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> </bean>
2.使用XML来启用组件扫描,使用spring context命名空间的<context:component-scan>元素。
<?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"> <context:component-scan base-package="soundsystem"/>
</beans>
3.<bean>: <bean>元素类似于JavaConfig中的@Bean注解。
<bean class="sdnu.machi.one"/>
创建这个bean的类通过class属性来指定,并且要使用全限定的类名。
因为没有明确给定ID,所以这个bean将会根据全限定类名来进行命名。在上述代码中,bean的id将会是"sdnu.machi.one#0"。其中,"#0"是一个计数的形式,用来区分相同类型的其他bean。如果你声明了另外一个one,并且没有明确进行标识,那么它自动得到的id将会是”sdnu.machi.one#1"。
通常来将更好的办法是借助id属性,为每个bean设置一个你自己选择的名字。
当spring发现这个<bean>元素时,它将会调用one的默认构造器来创建bean。(如果这时没有默认构造函数会报错)。
4.<constructor-arg>: 通过该元素可以在XML中实现依赖注入。如下
<bean id="one" class="sdnu.machi.one">
<constructor-arg ref="two" />
</bean>
当spring遇到这个<bean>元素时,它会创建一个one实例。<constructor-arg>元素会告知spring要将一个id为two的bean引用传递到one的构造器中(有参构造器)。
该元素还有value属性,通过该属性表明给定的值要以字面量的形式注入到构造器中。
5.c-命名空间: 它是在XML中更为简洁的描述构造器参数的方式。要使用它的话,必须要在XML的顶部声明其模式,如下:
xmlns:c="http://www.springframework.org/schema/c"
添加了命名空间和模式声明后,我们就可以使用它来声明构造器参数了,如下所示:
<bean id="one" class="sdnu.machi.one" c:cd-ref="two"/>
除了使用构造器参数名外,我们也可以使用参数在整个参数列表中的位置信息:
c:_0-ref:"two"
将参数的名称换成了“0”,也就是参数的索引,因为在XML中不允许数字作为属性的第一个字符,因此必须要添加一个下划线作为前缀。
在这里因为只有一个构造器参数,所以我们还有另外一种方案——根部不用去标示参数:
c:_-ref="two"
如果要注入的是字面量(基本数据类型以及string类型),参考代码如下:
c:_title="machi"
c:_content="is a good boy"
title和content是参数名,也可以通过索引进行装配,如下:
c:_0="machi"
c:_1="is a good boy"
下划线后面的数字指明了参数的索引。
6.<list>: 当需要注入集合时,可以在<constructor-arg>元素中使用<list>元素来声明列表,如下:
<constructor-arg>
<list>
<value>machi</value>
<value>is</value>
<value>a</value>
<value>good</value>
<value>boy</value>
</list>
</constructor-arg>
<list>元素是<constructor-arg>的子元素,这表明一个包含值的列表将会传递到构造器中。其中,<value>元素用来指明列表中的每个元素。
我们也可以使用<ref>元素代替<value>,实现bean引用列表的装配。
<ref bean="id名“/>
7.<set>: 与<list>元素作用相同。
8.<property>: <property>元素为属性的Setter方法所提供的功能与<constructor-arg>元素为构造器所提供功能是一样的。它也有ref属性。
9.p-命名空间: 作为<property>元素的代替方案。为了启用p-命名空间,必须要在XML文件中与其他的命名空间一起对其进行声明:
xmlns:p="http://www.springframework.org/schema/p
使用方式如下:
p:compactDisc-ref="compactDisc"
示例代码:
10.<import>: 在XML中,可以使用import元素来拆分XML配置
三.在Java中进行显式装配
其实就是JavaConfig类,需要和注解一起使用。
四.隐式的bean发现机制和自动装配(基于注解的隐式装配)
1.@Component: 在类上使用@Component注解,这个简单的注解表明该类会作为组件类,并告知spring要为这个类创建bean。
默认id为将类名的第一个字母变为小写。如果不想使用默认id,可以自定义id,如@Component("自定义id名“)。
2.@ComponentScan: 组件扫描默认是不启用的。我们需要显示配置一下spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。@ComponentScan注解能够在spring中启用组件扫描。如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包,即扫描这个包以及下面的所有子包,查找带有@Component注解的类。
为了指定不同的基础包,你所需要做的就是在@ComponentScan的value属性中指明包的名称,如@ComponentScan(”包名“)。如果你想要更加清晰地表名你所设置的是基础包,可以通过basePackages属性进行配置,如@ComponentScan(basePackeges=”包名“),如果你想要设置多个基础包,只需要将basePackages属性设置为要扫描包的一个数组即可,如@ComponentScan(basePackages={"包1”,“包2”,.....})。除了将包设置为简单的string类型之外,该注解还提供了另外一种方法,那就是将其指定为包中所包含的类或接口,如@ComponentScan(basePackageClassess={one.class, two.class}),这些类所在的包将会作为组件扫描的基础包。
3.@Named: 该注解作用与@Component基本相同。
4.@Autowired: 该注解是用来进行依赖注入的,它会寻找spring容器中适合的bean传递给该方法的参数。@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上。实际上该注解可以用在该类的任何方法上.
不管是构造器、Setter方法还是其他的方法,spring都会尝试满足方法参数上所声明的依赖。
如果没有匹配的bean,那么在应用上下文创建的时候,spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的required属性设置为false。将required属性设置为false时,spring会尝试执行自动装配,但是如果没有匹配的bean的话,spring会让这个bean处于未装配的状态。
如果有多个bean都能满足依赖关系的话,spring将会抛出一个异常,表名没有明确指定要选择哪个bean进行装配。
5.@Inject: 该注解作用与@Autowired相同。
6.@Configuration: 创建JavaConfig类的关键在于为其添加@Configuration注解,该注解表名这个类是一个配置类。
7.@Bean: 要在JavaConfig中声明bean,我们需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。如下:
@Bean
public CompactDisc sgtPeppers(){
return new SgtPeppers();
}
@Bean注解会告诉spring这个方法将会返回一个对象,该对象要注册为spring应用上下文中的bean。
默认情况下,bean的id与带有@Bean注解的方法名是一样的。在上述例子中,这个bean的id为sgtPeppers。你可以通过name属性指定一个不同的名字。@Bean(name=“id名”)。
如果你要借助JavaConfig实现注入该怎么做,通过下面这行代码可以实现注入:
@Bean
public CompactDisc sgtPeppers(){
return new SgtPeppers();
} @Bean
public CDPlayer cdPlayer(){
return new CDPlayer(sgtPeppers());
}
第二个bean需要注入第一个bean,所以在构造方法中调用了第一个方法。
可以看到,通过调用方法来引用bean的方法有点令人困惑。下面是一种更为简单的方法:
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
在这里,cdPlayer()方法请求一个CompactDisc作为参数。通过这种方法引用其他bean通常是最佳的选择,因为它不会要求将COmpactDisc声明到同一个配置之中。
8.@Import: 通过@Import注解将两个类组合在一起。
9.@ImportResource: 使配置在JavaConfig中的bean和配置在XML中的bean都会被加载到spring容器之中。
五.最后
最后想写一点与前面没有关系的东西,不久前在b站看到的了一个视频,题目很新颖,叫“不要做程序员”。up主在视频中并没有说程序员的不好,他只是说在这个编程十分流行的年代,我们不要为了编程而去编程,你要让你做出来的东西带来一些意义,编程只是解决问题的一种工具,而你要成为解决问题的那个人。
spring实战第二章小记-装配bean的更多相关文章
- #Spring实战第二章学习笔记————装配Bean
Spring实战第二章学习笔记----装配Bean 创建应用对象之间协作关系的行为通常称为装配(wiring).这也是依赖注入(DI)的本质. Spring配置的可选方案 当描述bean如何被装配时, ...
- Spring实战——通过Java代码装配bean
上篇说的是无需半行xml配置完成bean的自动化注入.这篇仍然不要任何xml配置,通过Java代码也能达到同样的效果. 这么说,是要把上篇的料拿出来再煮一遍? 当然不是,上篇我们几乎都在用注解的方式如 ...
- Spring实战之通过XML装配bean
尽管Spring长期以来确实与XML有着关联,但现在需要明确的是,XML不再是配置Spring的唯一可选方案.Spring现在有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择了. ...
- Spring实战第一章学习笔记
Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...
- spring在IoC容器中装配Bean详解
1.Spring配置概述 1.1.概述 Spring容器从xml配置.java注解.spring注解中读取bean配置信息,形成bean定义注册表: 根据bean定义注册表实例化bean: 将bean ...
- (转)java之Spring(IOC)注解装配Bean详解
java之Spring(IOC)注解装配Bean详解 在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看 ...
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring3实战第二章第一小节 Spring bean的初始化和销毁三种方式及优先级
Spring bean的初始化和销毁有三种方式 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法: 优先级第二通过 <bean& ...
- Spring实战笔记2---Bean的装配
创建应用对象之间协作关系的行为通常成为装配,该篇的主要内容有两个,一个Spring装配Bean的几种方式以及Spring表达式,事实上这两者是分不开的,在Spring中,对象无需自己负责查找或者创建与 ...
随机推荐
- java基础 -- 关键字final的用法
用法一(修饰变量): Final变量能被显式地初始化并且只能初始化一次.被声明为final的对象的引用不能指向不同的对象.但是final对象里的数据可以被改变.也就是说final对象的引用不能改变,但 ...
- linux-iptables匹配条件总结(一)
指定单个ip,示例如下: iptables -A INPUT -s 192.168.2.85 -j ACCEPT (基本操作)
一.版本控制的发展 1.用文件来做版本控制 我们在写论文.做方案等的时候,一般都会同时在文件夹中存在很多版本的文件. 例如: 这种方式很常用,在很多领域都是用这种方式来进行版本控制的. 2.本地版本控 ...
- 【汇编】1.汇编环境的搭建:DOSBox的安装
前言 DOSBox是一款在windows系统运行DOS程序的环境模拟器.可以解决在64位机中汇编程序编译调试等问题. 本文以 DOSBox 0.74 为例,汇编编译程序采用MASM6. 第一步下载相关 ...
- js中的事件委派
在介绍JS中事件委派之前先来看看一个简单的需求:为每一个超链接绑定一个单击响应函数并在控制台打印一句话,内容是:” a 标签的单击响应函数“.下面是这个需求的代码: <!DOCTYPE html ...
- 小小知识点(三十一)MU-MIMO和SU-MIMO分别表示什么?
MU-MIMO是“Multi-User Multiple-InputMultiple-Output”的缩写,直译为“多用户多入多出技术”. SU-MIMO是“Single-User Multiple- ...
- KMP 和 扩展KMP
KMP:在主串S中找子串T的位置KMP算法的时间复杂度O(|S|+|T|). #define maxn 1000 char s[maxn],t[maxn];//s为主串,t为子串 int net[ma ...
- Flask 作者 Armin Ronacher:我不觉得有异步压力
英文 | I'm not feeling the async pressure[1] 原作 | Armin Ronacher,2020.01.01 译者 | 豌豆花下猫@Python猫 声明 :本翻译 ...
- Linux Cgroup浅析
cgroup从2.6.4引入linux内核主线,目前默认已启用该特性.在cgroup出现之前,只能对一个进程做资源限制,比如通过sched_setaffinity设置进程cpu亲和性,使用ulimit ...
- tantivy&lucene功能,写入性能对比
硬件概述:cpu:24,内存:20g,磁盘:10*2.7T. 写入性能:(不对ip进行添加geo信息). 写入性能对比 速度 Commit耗时(秒) 500*1000条 Bulk耗时(秒) 1000条 ...