关键词:
目录
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也可用用在变量上
二、通过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... 查看详情