spring实战读书笔记spring装配bean(代码片段)

xiueer xiueer     2022-12-02     216

关键词:

目录

一、自动装配bean

1、组件扫描

2、自动装配

二、通过Java代码装配Bean

1、简单配置

2、依赖注入

三、通过Xml装配Bean

借助构造器注入初始化bean

设置属性

混合配置


Spring容器负责创建应用程序中的bean并通过DI来装配(wiring)他们。Spring有三种装配方式,三种方式可以搭配使用

 

(1)隐式的bean发现机制和自动装配(推荐使用)

(2)在java中显式装配

(3)在xml中显式装配

一、自动装配bean

Spring从2个角度实现自动装配

1、组件扫描:自动发现应用上下文中所创建的bean

2、自动装配:Spring自动满足bean之间的依赖

1、组件扫描

//例子,CD和CDPlayer

// CD接口
package soundsystem;

public interface CompactDisc 
    void play();


//实现类
package soundsystem;

import org.springframework.stereotype.Component;

@Component //组件注解
public class SgtPeppers implements CompactDisc 

    public void play() 
        System.out.println("play SgtPeppers");
    

在上面的例子中,SgtPeppers类上加了@Component注解,这个注解就表明该类是一个bean,Spring会自动识别到该bean并处理。Spring还支持使用@Named注解作为@Component的替代方案,使用较少。Spring会为每一个bean设定一个ID,默认情况下,未类型首字母小写,上例中bean id为sgtPeppers。如果需要显式的指定bean id,只需要将期望的ID值传递给@Component注解

@Component("longlyHeatsClub")// 指定bean id
public class SgtPeppers implements CompactDisc 
    ...

不过组件扫描默认是不开启的,需要显式的配置开启组件扫描。Spring提供了2种配置方式:Java方式和xml方式。

java方式开启组件扫描

package soundsystem;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan//开启组件扫描
public class CDPlayerConfigs 

只需要新建一个配置类,并在该类上添加@ComponentScan注解变可以开启组件扫描。在例子中@ComponentScan没有加任何的参数,默认是扫描该配置类所在的包及其子包。如果要显式设定需要扫描的基础包,只需要在注解后面加上basePackages属性即可

@ComponentScan(basePackages="soundsystem")//指定基础包的报名
public class CDPlayerConfigs 


@ComponentScan(basePackages="soundsystem","video")//指定多个基础包的报名
public class CDPlayerConfigs 

以上的指定基础包的包名为字符串形式的,这种方式是类型不安全的,可能存在配置错误的情况。Spring还提供了一种方式,可以通过指定包中所包含的类或接口的方式配置。这些类所在的包将会被作为组件扫描的基础包。

@ComponentScan(basePackageClasses = CDPlayer.class, DVDPlayer.class)
    public class CDPlayerConfigs 

在实际使用中,可以考虑在包中单独创建一个用来进行扫描的空标记接口,将这些空标记接口配置在@ComponentScan中即可为需要的包开启组件扫描。

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: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>

以xml方式开启组件扫描需要要加入Context:component-scan元素即可。可以看到,xml方式开启组件扫描明显要比java方式复杂。

2、自动装配

自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。可以使用@Autowired开启自动装配。

package soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPalyer 
    private CompactDisc cd;

    @Autowired //自动装配
    public CDPlayer(CompactDisc cd)
        this.cd = cd;
    
    @Override
    public void play() 
        cd.play();
    

@Autowired不仅可以用在构造方法上,还可以用在setter和其他任何方法上。在Spring初始化bean之后,他会尽可能的满足bean的依赖。如果找不到匹配bean,会抛出异常。可以设置required=false避免抛出异常。(谨慎使用)

 @Autowired(required=false)
    public CDPlayer(CompactDisc cd)
        this.cd = cd;
    

@Autowired也可用用在变量上

@Autowired写在变量上和构造器上的区别

@Autowired:构造函数注入和变量注入

二、通过Java代码装配Bean

大部分场景下都可以使用自动装配的方式实现自动化配置,但是在某些场景下还是需要显式的配置bean的,比如想要将第三方库中的组件装配到应用中,我们无法在别人的代码上添加@Component和Autowired注解。此时,就需要显式的配置了,Spring提供了2种显式配置的方式:Java和Xml。Java配置是比Xml更好的配置方式,他更强大,类型安全并且对重构友好。

现在,把前面例子中的@ComponentScan和@Component注解去掉。

...
public class SgtPeppers implements CompactDisc 

    public void play() 
        System.out.println("play SgtPeppers");
    

要如何获取到SgtPeppers bean呢?

1、简单配置

在JavaConfig中,写一个方法返回一个SgtPeppers,并添加@Bean注解就可以啦。@Bean注解会告诉Spring这个方法会返回一个对象,并且这个对象要注册为Spring应用上下文中的Bean。默认bean id与方法名是一样的,也可以指定bean id。

    @Bean // 默认bean id为sgtPeppers
    public CompactDisc sgtPeppers()
        return new SgtPeppers();
    

    @Bean(name = "lonelyHeartsClueBead")
    public CompactDisc sgtPeppers()
        return new SgtPeppers();
    

在这个方法中,可以加入自己的逻辑,这样实际上为bean创建赋予了极大的灵活性。只要最终返回的是一个CompactDisc即可。

2、依赖注入

以上是简单情况下的bean配置。如果要装配的bean又依赖于其他的bean呢?

    @Bean
    public CompactDisc sgtPeppers()
        return new SgtPeppers();
    

    @Bean
    public CDPlayer cdPlayer()
        return new CDPlayer(sgtPeppers());
    

这样就可以实现cdPlayer的bean装配了。只不过这里需要注意的是,看起来在创建cdPlayer实例的时候是是通过调用sgtPeppers()得到的,但是sgtPeppers()上是添加了@Bean注解的,所以实际上Spring会拦截所有对它的调用,并直接返回在Spring应用上下文中的那个bean(默认情况下,Spring的bean都是单例的)。所有无论有多少个方法调用sgtPeppers()的bean,其实都是用一个bean。

    // 2个sgtPeppers()返回的bean是同一个
    @Bean
    public CDPlayer cdPlayer()
        return new CDPlayer(sgtPeppers());
    

    @Bean
    public CDPlayer cdPlayer2()
        return new CDPlayer(sgtPeppers());   
    

当然,以上代码其实不是最好的依赖注入方式。下面的方式看起来更加的易于理解

    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc)
        return new CDPlayer(compactDisc);
    

cdPlayer 方法有一个参数,当Spring创建cdPlayer bean的时候,会自动为其装配一个CompactDisc。而且通过这种方式装配cdPlayer便不需要将compactDisc声明在同一个配置类中。他可以以任意的形式配置(Java/Xml),只要是一个Spring的bean即可。

三、通过Xml装配Bean

声明一个简单的bean

    <bean class="soundsystem.SgtPeppers"/> <!-- 默认bean id为SgtPeppers#0,其中#0是序号 -->
    <bean id="sgtPeppers"  class="soundsystem.SgtPeppers"/> <!-- 指定bean id-->

借助构造器注入初始化bean

在xml中声明DI时,有多种可选的配置方案,具体到构造器注入,可以有2种基本的配置方案(1)<constructor-arg>方案(2)使用Spring3.0所引入的c-命名空间

    public CDPlayer cdPlayer(CompactDisc compactDisc)
        return new CDPlayer(compactDisc);
    

我们以上面的bean为例,假设需要创建这个bean,并且注入CompactDisc bean。可以使用如下方式注入bean引用。

    方式1
    <bean id="cdPlayer" class="soundsystem.CDPlayer">
        <constructor-arg ref="sgtPeppers"/>     //假设sgtPeppers已经在其他地方定义好了
    </bean>

    方式2
    <bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="sgtPeppers"/>

除了可以注入bean的引用意外,还可以将字面量注入到构造器中。也可以将list/set集合注入到构造器中,而此集合中的元素又可以是字面量或者bean引用。

设置属性

假设存在如下的CDPlayer

package soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPalyer 
    private CompactDisc cd;

    @Autowired
    public void setCompactDisc(CompactDisc cd)
        this.cd = cd;
    
    @Override
    public void play() 
        cd.play();
    

为了注入CDPlayer的cd属性,我们需要定义如下的bean

    方法1 property属性注入
    <bean id="cdPlayer" class="soundsystem.CDPlayer">
        <property name="compactDisc" ref="sgtPeppers"/>
    </bean>

    方法2 p命名空间注入
    <bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="sgtPeppers"/>

同样的,除了为属性注入引用意外,还可以为其注入字面量(p命名空间不能注入集合)

混合配置

一般的项目规模较大是,不会只有一个配置文件,这时候可能就设计到配制之间的引用。

// Java中引用java
@Configuration
@Import(CDConfig.class)
public class CDPlayerConfigs ...

// Java中引用xml
@Configuration
@ImportResource("classpath:springConfig.xml")
public class CDPlayerConfigs ...
    <!--xml中引用xml-->
    <import resource="SpringConfig2.xml"/>

    <!--xml中本身无法引用java配置,可以通过将java config定义为一个bean的方式间接引用这个java配置-->
    <bean class="soundsystem.CDConfig"/>

当然是实际使用中,更常用的做法是定义一个更高层的配置文件(无论是java还是xml),其中引用所有的分模块的配置,以实现统一管理

 

 

spring实战笔记二

一、Spring配置的方式    spring容器用来创建应用程序中的bean,并通过DI来协调这些对象间的关系。    在bean进行装配时,spring提供了三种主要的装配机制。      ①在XML中进行显式配置      ②在Java中进... 查看详情

《spring实战》学习笔记-第二章:装配bean

2.1 Spring配置的可选方案  当描述bean如何进行装配时,Spring具有非常大的灵活性,它提供了三种主要的装配机制:  (1)在XML中进行显式配置。  (2)在Java中进行显式配置。  (3)隐式的bean发现机制和自动装配。  建议是... 查看详情

springinaction读书笔记--第2章装配bean

...致结构复杂的代码,这些代码很难被复用和单元测试。在Spring中,对象不需要自己寻找或创建与其所关联的其它对象,Spring容器负责把需要相互协作的对象引用赋予各个对象。创建对象之间协作关系的行为称为装配,这也是依赖... 查看详情

spring实战-第二章-装配bean

Bean是Spring对象的声明(装配wiring),要使用Spring,必须先装配需要使用的对象,有3种装配的方式自动化装配Bean通过Java代码装配通过XML装配自动化装配Bean自动化装配Bean很简单1.声明接口packagesoundsystem;publicinterfaceCompactDisc{voidplay(... 查看详情

spring学习笔记——装配bean

1、Spring配置的可选方案在XML中进行显式配置。Java中进行显式配置。隐式的bean发现机制和自动装配。 2、自动化装配bean  Spring从两个角度来实现自动化装配:组件扫描(componentscanning):Spring会自动发现应用上下文中所创... 查看详情

<spring实战>2:装配bean

1声明Bean1.1创建Spring配置  Spring容器提供两种配置Bean的方式:xml配置和基于注解配置。  Spring配置文件:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org 查看详情

spring4.0学习笔记——自动装配

SpringIOC容器可以自动装配Bean,需要做的是在<bean>的autowire属性里指定自动装配的模式1)byType根据类型自动装配,若IOC容器中有多个目标Bean类型一致的Bean,Spring将无法判定哪个Bean最适合该属性,不能执行自动装配2)byName根据... 查看详情

spring4实战学习笔记

《Spring4实战第4版》2016年4月新出版的,之前的第三版看起来还是不错的,所以看到新版就直接买下来。英文版源码地址:SpringinAction,FourthEditionCoversSpring4 1.IOC装配Bean参考【Spring实战4 2.2】,作者提倡无XML配置化... 查看详情

spring实战读书笔记spring之旅(代码片段)

Spring可以做很多事情,但是这个事情底层都依赖于2个核心特征:依赖注入(DI)和面向切面编程(AOP)概念:POJO:简单java对象,PlainOldJavaObject,在Spring中基本可以等同于javabean为了简化Java... 查看详情

spring实战第二章小记-装配bean

 时间:2020/02/06 一.思想1.创建应用对象之间协作关系的行为通常称为装配,这也是依赖注入(DI)的本质。对于上面这句话的个人理解:当我们在new一个对象时如果传入了别的对象作为参数(这个对象可能是引用数据类型... 查看详情

<spring实战>3:最小化springxml配置

1自动装配Bean属性1.14种类型的自动装配byName:把与Bean的属性具有相同名字或ID的其他Bean自动装配到Bean的对应属性中byType:把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中constructor:把与Bean的构造器入参具有相... 查看详情

spring学习笔记—装配bean(代码片段)

                       Spring学习笔记—装配Bean  在Spring中,对象无需自己负责查找或创建与其关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间协作关系的行为... 查看详情

spring学习笔记—装配bean(代码片段)

                       Spring学习笔记—装配Bean  在Spring中,对象无需自己负责查找或创建与其关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间协作关系的行为... 查看详情

spring4学习笔记-配置bean-自动装配关系作用域引用外部属性文件

1Autowire自动装配 1.1使用:只需在<bean>中使用autowire元素 <beanid="student"class="com.kejian.spring.bean.autowire.Student" p:name="Tony"autowire="byName"></bean> 1.2类型 byName目标bean的id与属性名一置, 查看详情

学习笔记——spring管理第三方bean;spring中bean的作用域;spring中bean的生命周期;spring中bean的后置处理器;spring中自动装配(代码片段)

2023-01-17一、Spring管理druid步骤 (1)导入jar包<!--https://mvnrepository.com/artifact/com.alibaba/druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artif 查看详情

spring实战读书笔记spring之旅(代码片段)

Spring可以做很多事情,但是这个事情底层都依赖于2个核心特征:依赖注入(DI)和面向切面编程(AOP)概念:POJO:简单java对象,PlainOldJavaObject,在Spring中基本可以等同于javabean为了简化Java... 查看详情

使用spring的命名空间p装配属性-摘自《spring实战(第3版)》

...t;元素为Bean的属性装配值和引用并不太复杂。尽管如此,Spring的命名空间p提供了另一种Bean属性的装配方式,该方式不需要配置如此多的尖括号。命名空间p的schemaURL为http://www.springframework.org/schema/p。如果你想使用命名空间p,只... 查看详情

spring实战-bean作用域

Spring定义了多种域单例(Singleton):在整个应用中,只有一个实例原型(Prototype):每次注入或者通过Spring应用上线文获取时,都创建一个bean实例会话(Session):在web应用中,为每个会话创建一个bean.使用场景:购物车请求(Re... 查看详情