时间: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的更多相关文章

  1. #Spring实战第二章学习笔记————装配Bean

    Spring实战第二章学习笔记----装配Bean 创建应用对象之间协作关系的行为通常称为装配(wiring).这也是依赖注入(DI)的本质. Spring配置的可选方案 当描述bean如何被装配时, ...

  2. Spring实战——通过Java代码装配bean

    上篇说的是无需半行xml配置完成bean的自动化注入.这篇仍然不要任何xml配置,通过Java代码也能达到同样的效果. 这么说,是要把上篇的料拿出来再煮一遍? 当然不是,上篇我们几乎都在用注解的方式如 ...

  3. Spring实战之通过XML装配bean

    尽管Spring长期以来确实与XML有着关联,但现在需要明确的是,XML不再是配置Spring的唯一可选方案.Spring现在有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择了. ...

  4. Spring实战第一章学习笔记

    Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...

  5. spring在IoC容器中装配Bean详解

    1.Spring配置概述 1.1.概述 Spring容器从xml配置.java注解.spring注解中读取bean配置信息,形成bean定义注册表: 根据bean定义注册表实例化bean: 将bean ...

  6. (转)java之Spring(IOC)注解装配Bean详解

    java之Spring(IOC)注解装配Bean详解   在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看 ...

  7. Spring入门2. IoC中装配Bean

    Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...

  8. Spring3实战第二章第一小节 Spring bean的初始化和销毁三种方式及优先级

    Spring bean的初始化和销毁有三种方式 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法: 优先级第二通过 <bean& ...

  9. Spring实战笔记2---Bean的装配

    创建应用对象之间协作关系的行为通常成为装配,该篇的主要内容有两个,一个Spring装配Bean的几种方式以及Spring表达式,事实上这两者是分不开的,在Spring中,对象无需自己负责查找或者创建与 ...

随机推荐

  1. `docker数据持久化volume和bind mounts两种方式

    将数据从宿主机到容器的三种方式: ,volumes:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)保存数据的最佳方式 ,bind mounts 将宿主机上的任 ...

  2. 【汇编】AX内容依次倒排序

    ;P99,5.13,ax内容倒序 ;思路,ax左移一位最高位进cf里,bx右移一位把cf里值进bx的最高位, ;循环16次即实现ax16位内容倒序存储在bx中 DATA SEGMENT DATA EN ...

  3. Linux开发环境及应用—《第三周单元测验》《第四周单元测验》

    三单元 1.vi处于文本输入状态时,按下下列哪个按键可以返回命令状态?C A.^ B.$ C.Esc D- 2.vi处于命令状态时,按下下列哪组按键可以把正在编辑的内容保存到磁盘上?D A.Ctrl- ...

  4. 小小知识点(四十一)-based和based on的正确理解

    A-based B<等价于>B based on A<等价于>B on the basis of A,翻译为基于A的B For example: (1) Radar-based ...

  5. .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

    介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还 ...

  6. php改变时间的方法

    1. strtotime date("Y-m-d",strtotime('+1day')) 2. mktime date("Y-m-d",mktime(0,0, ...

  7. 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  8. python命名空间(namespace)

    命名空间: 每一个作用域变量存储的位置,或者解释为 存储作用域中变量的字典. 作用: 获取想查看某个作用域中的变量名.变量值. 使用方法: locals()  #当前命名空间 1. 效果图: 2. 代 ...

  9. Java 利用Map集合计算一个字符串中每个字符出现的次数

    步骤分析 1.给出一串字符串,字符串中可以包含字母.数字.符号等等. 2.创建一个Map集合,key是字符串中的字符,value是字符的个数. 3.遍历字符串,获取每一个字符. 5.使用获取到的字符, ...

  10. ES6的Object.assign()基本用法

    Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 例如: const target = {a:1}, const source1 ...