【J2EE学习笔记】Spring基本配置

在Spring容器内拼接Bean称为装配(wiring),Spring提供了三种主要的装配机制:

1、在XML中进行显式配置

2、在Java中进行显式配置

3、隐式的bean发现机制和自动装配

尽可能地使用自动配置机制,显式配置越少越好。当你必须要显示配置bean的时候,推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML。

自动化装配bean

Spring从两个角度来实现自动化装配:

组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。

@Component

@Component注解表明该类会作为组件类,并告知Spring要为这个类创建bean。不过,组件扫描默认是不启用的,我们还需要显示配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。使用@Component时候如果不命名,则系统会自动根据类名来命名bean,否则可以使用@Component("名称")来给bean命名。

@ComponentScan

@ComponentScan注解启用了组件扫描,如果没有其他配置,默认会扫描与配置类相同的包,查找带有@Component注解的类,并且会在Spring中自动为其创建一个bean。如果我们想扫描不同的包,或者多个基础包,或者是将配置类放在单独的包里,使其与其他的应用代码区分开来,可以在@ComponentScan的value属性中指明包的名称:

@ComponentScan("包名")

如果想更加清晰地表明所设置的是基础包,可以通过basePackages属性进行配置:

@ComponentScan(basePackages="包名")

basePackages是复数形式的,也就意味着你可以扫描多个基础包,只需要将basePackages属性设置为要扫描包的一个数组即可:

@ComponentScan(basePackages={"包名1","包名2","包名n"})

这种方法设置基础包是以String类型表示的,但是这方法类型不安全,重构代码后可能会出现错误。

@ComponentScan还提供了另外一种方法,就是将其指定为包中所包含的类或接口:

@ComponentScan(basePackageClasses={实例名1.class,实例名2.class,实例名n.class})

或者可以通过XML来启动组件扫描,添加下列4句加黑的代码即可

<?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"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
	<context:component-scan base-package="包名"/>
</beans>

如果我们要将组件扫描得到的bean和它们的依赖装配 在一起,则需要自动装配技术

自动装配(autowiring):Spring自动满足bean之间的依赖,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行自动装配,我们可以使用Spring的@Autowired注解。

@Autowired注解不仅能够用在构造器上,还能用在属性Setter方法上,在Spring初始化bean之后,它会尽可能得去满足bean的依赖。其实@Autowired注解可以用在类的任何方法上,不管是构造器,Setter方法还是其他的方法,Spring都会尝试满足方法参数上所声明的依赖。如果没有匹配的bean,那么Spring会抛出一个异常。为了避免异常,可以将@Autowired的required属性设置为false:

@Autowired(required=false)

这样,如果Spring找不到匹配的bean,将会让这个bean处于未装配的状态,所以要小心使用required属性设置,可能会出现NullPointerException异常。

通过Java代码装配bean

有时候不能使用自动化配置,因此需要明确配置Spring。比如:你想要将第三方库中的组件装配到你的应用,这时候没法给它的类添加@Component和@Autowired注解。因此需要显示的装配方式。

在进行显式配置时,JavaConfig是更好的方案,因为它更为强大、类型安全并且对重构友好。JavaConfig与其他的Java代码一样,但是它不包含任何业务逻辑,也不应该侵入到业务逻辑代码之中,通常会将JavaConfig放到单独的包中,与应用程序逻辑分离开来。

创建JavaConfig类的关键在于为其添加@Configuration注解,@Configuration注解表面这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。

要在JavaConfig中声明bean,需要一个方法来创建所需类型的实例,然后给这个方法添加@Bean注解。

@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了产生bean实例的逻辑。要给这个bean命名,可以使用name属性指定一个不同的名字:

@Bean(name="名字")

如:

@Bean(name="lonelyHeartsClubBand")
public CompactDisc sgtPeppers() {
    return new SgtPeppers();
}

这里声明bean时候没有任何依赖,如果我们要在JavaConfig中将bean和它的依赖装配在一起,最简单的方式就是引用创建bean的方法。如:

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

这表明这个方法会创建一个bean实例,并将其注册到Spring应用上下文中。这样就将CDPlayer和它依赖的CompactDisc装配在了一起。这里没有使用默认的构造器构建实例,而是调用了需要传入CompactDisc对象的构造器来创建CDPlayer实例。

还有另一种方法:

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
}
这里cdPlayer()方法请求一个CompactDisc作为参数。当创建cdPlayerbean时候,它会自动装配一个CompactDisc到配置方法之中,这样不用明确引用CompactDisc的@Bean方法,这通常是最佳的选择。


通过XML装配bean

在XML中装配,需要一个XML文件,并且要以<beans>元素为根

要声明一个bean,我们需要使用<bean>,类似于JavaConfig中的@Bean注解,如

<bean class="包.类名" id="命名">

创建这个bean的类通过class属性来指定,并且要使用全限定的类名。id属性可以给这个bean命名。当Spring发现这个<bean>元素时,会调用对应的默认构造器来创建bean,不用像JavaConfig中要自己创建实例。

可以有两种方法来注入:

使用<constructor-arg>元素或使用Spring 3.0引入的c-命名空间,两者区别在很大程度就是是否冗长繁琐。

例:

<bean id="cdPlayer" class="soundsystem.CDPlyer">
    <constructor-arg ref="compactDisc" />
</bean>

当Spring碰到这个<bean>,会自动创建CDPlayer实例,并且会将一个叫compactDisc的bean引用传递到CDPlayer的构造器中。

或者使用c-模式:

...
xmlns:c="http://www.springframework.org/schema/c"
...
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc" />

这里使用了c-命名空间来声明构造器参数。"c:"是命名空间的前缀,"-ref"告诉Spring,装配的是一个bean的引用,"cd"是参数名。

之前所做的DI都是类型的装配,如果我们需要用一个字面量值来配置对象,则我们可以使用

 <constructor-arg value="值"/>

来进行构造器参数的注入。

如果是用c-命名空间,则是:

<bean id="命名" class="包名.类名" c:_参数名1="值" c:_参数名2="值" c:_参数名n="值" />

装配字面量不再需要-ref。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值