Spring实战(二)装配bean

Spring配置可选方案:

1.在XML中进行显示装配;

2.在java中进行显示装配;

3.隐示bean发现机制和自动装配;

4.互相搭配

一.自动化装配bean(@Component和@Autowired)

    1.组建扫描:Spring会自动发现应用上下文中所创建的bean。

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

          两者结合,发挥出巨大的作用。

1).使用@Component(***)注解,表明该类会作为组件类,并告知Spring要为这个类创建Bean,***一般为bean的ID。(注:组建扫描默认是不会开启的,需要显示配置一下Spring,命令它去寻找带有@Component注解的类,并为其创建bean,java装配的话使用@ComponentScan注解(如果没有其他配置的话,它会在自己所在的包中扫描),XML的话使用Spring context命名空间的<context:component-scan>元素,其他属性和子元素就不写了)。

2).@Name(***),属于java依赖注入规范JDI (java Dependency Injection),和@Component在大多数场景中是可以互换的,两者之间只有细微的差别。

3).注解@ContextConfiguration(***)会告诉你要在***中加载配置(***通常为java的配置文件或XML的配置文件,通过它可以自动扫描到所注入的bean)。

4).@ComponentScan(***),1)中已经介绍,***可以是"(基础包)",也可以是"basePackages="(基础包1),(基础包    2)"可以添加多个基础包。如果感觉不安全的话,可以使用basePackageClasses="(类名1),(类名2)"。

5).@Autowired注解不仅能够用在构造器上,还能用到setter方法上,来实现自动装配。有required属性,当为false时,spring会尝试自动装配,如果没有bean时,会让这个bean处于未装配的状态不会报错。

6).@Inject注解,来自JDI,与@Autowired有细微的差别,但大多数是可以相互替换的。

二.通过java代码装配bean

1.下面是一个配置类(import和package忽略)

@Configuration
public class CDPlayerConfig{
}

通过添加注解@Configuration可以实现配置类,注意导入支持类。这里添加自动扫描组件了。

2.添加@Bean可以让对象注册为spring应用上下文中的bean

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

如果没有name的话,bean默认名字为方法名,可以通过设置name重命名。

3.借助JavaConfig实现注入:

1.最简单方法就是引用创建bean的方法例如(构造器注入)

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

cdPalyer方法就像sgtPeppers方法一样,来产生CDPlayer Bean,但是还是有区别的,这里并没有使用默认构造器构建实例,而是调用了需要传入CompactDisc对象的构造器来创建的。问题来了,它是否就像方法一样,会产生一个bean,事实上,Spring会将产生的已有的bean注入,注入不同的bean的CompactDisc的bean只有一个。是将同一个SgtPeppers实例注入到任意数量的其他bean中。默认情况下,Spring中的bean都是单例。所以,Spring会拦截对sgtPeppers的调用,并返回的是Spring创建的bean。也就是Spring本身在调用sgtPeppers()时创建爱你的CompactDisc bean。

2.理解起来更为简单的方式(构造器注入)

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

当Spring调用cdPlayer()创建CDPlayer bean时,它会自动装配一个CompactDisc到配置方法中。借助这种技术,也可以实现注入到构造器中,而不用明确应用CompactDisc的@Bean方法。通常这种方法是最佳的选择,因为它可以让Spring通过任何方式去装配CompactDisc bean,甚至不再javaconfig中声明。

3.其实也可通过Setter方法去注入,(带有@Bean注解的方法可以采用任何必要的java功能来产生bean实例,仅仅受到java语言的限制)

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
	//CDPlayer cdPlayer = new CDPlayer(compactDisc);
	cdPlayer.setCompactDisc(compactDisc);
	return cdPlayer;
}

三.通过XML装配bean

创建和管理Spring XMl配置文件的一种简单的方式是使用SPring Tool Suite

最为简单的配置如下所示:

<?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-4.1.xsd">

       <!-- 配置一个bean -->
       <bean id="compactDisc"  class="soundsystem.SgtPeppers" >
            <!--给构造函数传递参数,没有的话则调用默认构造方法  -->
            <constructor-arg value="15"/> 
       </bean>
       <bean  class="soundsystem.SgtPeppers"/>

       <bean id="poeticDuke" class="springAction.PoeticJuggler">
            <constructor-arg value="22"></constructor-arg>
            <!-- 基本数据类型参数用value=字符串(Spring根据构造参数类型自动解析字符串),
                             引用类型的参数用ref= bean id -->
            <constructor-arg ref="sonnet29"></constructor-arg>
       </bean>

       <!-- factory-method通过工厂方法将单例类配置为bean,因为Stage没有构造函数 -->
       <bean id="theStage" class="springAction.Stage" factory-method="getInstance">
       </bean>
</beans>

在声明一个简单的bean,创建这个bean的类通过class属性来指定,并且使用全限定的类名。bean的id将会是“soundsystem.SgtPeppers#0”,“#0”是一个计数形式,用来区分相同类型的其他bean。是累加结果。

<bean  class="soundsystem.SgtPeppers"/>

这是给予id

 <bean id="compactDisc"  class="soundsystem.SgtPeppers" >

1.构造器注入初始化bean

有两种基本的配置方案可供选择:

1).<constructor-arg>元素;

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

2).使用spring3.0所引入的c-命名空间。(后者会使xml更加简洁,但有些功能是无法完成的。)

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

cd:是参数的名字,-ref:注入bean引用,"compactDisc":bean的id,参数名字这里不推荐,因为在编译时会出错,替代方法按参数索引,比如:

<bean id="cdPlayer" class="soundsystem.CDPlayer"
      c:_0-ref="compactDisc"/>

第二个参数为_1以此类推。

上面讲的是bean注入,下面来说一下将字面量注入到构造器中:

<bean id="cdPlayer" class="soundsystem.CDPlayer">
  	<constructor-arg value="****">
        <constructor-arg value="****">
</bean>
<bean id="cdPlayer" class="soundsystem.CDPlayer"
      c:_name1="***"        c:_name2="***"/>
<bean id="cdPlayer" class="soundsystem.CDPlayer"
      c:_0="***"        c:_1="***"/>

大致就是将ref换成value

装配集合:

list项目为string

<constructor-arg>
	<list>
		<value>**</value>
		<value>**</value>
	</list>
</constructor-arg>
list项目为为bean

<constructor-arg>
	<list>
		<ref bean="***">
		<ref bean="***">
	</list>
</constructor-arg>

2.设置属性(通过setter方法,但不限于)

1)

<bean id="cdPlayer" class="sounsystem.CDPlayer">
	<property name = "***" value="***">
	<!-- bean--->
	<property name="***" ref="***">
	<property name = "***">
		<list>
			<vlaue>***</vlaue>
			<value>***</value>
		</list>
	</property>
	<!--bean-->
	<property name = "***">
		<list>
			<ref bean="***"/>
			<ref bean="***"/>
		</list>
	</property>
</bean>
使用p-命名空间
xmlns:p="http://www.springframework.org/schema/p"
<bean id="cdPlayer" class="sounsystem.CDPlayer" 
p:compactDisc-ref="compactDisc" p:name="***"/>

与c-命名空间类似

3.使用util:list

<util:list id="trackList">
	<value>***</value>
	<value>***</value>
</util:list>

<util:list id="***">
	<ref bean="***">
	<ref bean="***">
</util:list>

<bean id="cdPlayer" class="sounsystem.CDPlayer"
p:tracks-ref="trackList"/>

相当于创造了一个list的bean注入到目标bean中

Spring util-命名空间中的元素:


<util:constant> 引用某个类型的public static 域,并将其暴露为bean
<util:list>    创建一个java.util.List 类型的bean,其中包含值或引用
<util:map>     创建一个java.util.Map 类型的bean,其中包含值或引用
<util:properties> 创建一个java.util.properties类型的bean
<util:property-path> 引用一个bean属性(或内嵌属性),并将其暴露为bean
<util:set>     创建一个java.util.Set 类型的bean,其中包含值或引用

四.导入和混和配置 

1.在javaconfig中引用XML配置

如果两个bean在两个不同的Java配置类中我们可以在任意一个中用@Import(类1.class,类2.class,....)去导入配置类,但是最好的方法是建立一个包的配置类,将多个配置类一起导入其中。

如果其中有的配置在XML中,我们可以使用注解@ImportResource("classpath:****.xml")导入配置类中。

2.在XML配置中引用javaconfig

如果是Java配置类的话可以使用<bean class="路径">,如果是XML配置文件的话可以使用<import resource="***.xml">


不管使用javaconfig还是XML装配,建议创建一个更配置(root configuration),这个配置会将多个配置类或xml文件组合在一起

。通常也会在根配置中启用组件扫描(<context:component-scan>或者@ComponentScan)。

















猜你喜欢

转载自blog.csdn.net/weixin_40132006/article/details/80633455