spring装配bean

Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。但作为开发人员,需要告诉spring创建哪些bean并且如何装配。spring提供了三种主要的装配机制:

  • 在xml中进行显示配置
  • 在java中进行显示配置
  • 隐式的bean发现机制和自动装配

自动化装配bean

使用@component 注解创建可被spring发现的bean。例如:

package springdemo.test1.entity.impl;

import org.springframework.stereotype.Component;

import springdemo.test1.entity.ICar;

@Component
public class AudiCar implements ICar{

    String carName = "audi";
    
    @Override
    public void drive() {
        System.out.println(carName + "is running");
    }
}

AudiCar使用了@Component注解,spring通过启用组件扫描,会自动寻找带有@Component注解的类,并为其创建bean。

启用组件扫描有两种方式:

  • 使用java配置
  • 使用xml启用

java配置启用:

package springdemo.test1.entity.config;

import org.springframework.context.annotation.ComponentScan;

@Configuration @ComponentScan
public class CarConfig { }

类CarConfig使用@ComponentScan注解启用组件扫描,默认会扫描与配置类相同的包。

可以发现CarConfig和AudiCar在不同的包中(方便管理),因此还需要配置扫描的基础包:

  • 直接设置value属性
@Configuration
@ComponentScan("impl")
public class CarConfig {

}
  • 使用basePackages属性设置
@Configuration
@ComponentScan(basePackages="impl")
public class CarConfig {

}
  • 使用basePackages属性设置多个
@Configuration
@ComponentScan(basePackages= {"impl","config"})
public class CarConfig {

}
  • 使用basePackageClasses,会设置这些类所在的包为扫描基础包
@Configuration
@ComponentScan(basePackageClasses= {ICar.class,CarConfig.class})
public class CarConfig {

}

使用xml启用:

<context:component-scan base-package="springdemo.test1.entity.impl" />

通过为bean添加注解实现自动装配 (@Autowired)

package springdemo.test1.entity.impl;

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

import springdemo.test1.entity.ICar;
import springdemo.test1.entity.IEngine;

@Component
public class AudiCar implements ICar{

    String carName = "audi";
    
    private IEngine engine;
    
    @Autowired
    public AudiCar(IEngine engine) 
    {
        this.engine = engine;
    }
    
    @Override
    public void drive() {
        engine.output();
        System.out.println(carName + "is running");
    }
    
}

@Autowired注解不仅能够用在构造器上,还能用在属性的setter方法上。

    @Autowired
    public void setIEngine(IEngine engine) 
    {
        this.engine = engine;
    }

在spring初始化bean之后,它会尽可能得去满足bean的依赖。不管是构造器、setter方法还是其他方法,spring都会尝试满足方法参数上所声明的依赖。假如有且只有一个bean匹配依赖需求的话,那么这个bean将会被装配进来。

通过java代码装配bean

使用@Configuration 注解创建配置类,该类应该包含spring应用上下文中如何创建bean的细节。

要在javaconfig中声明bean,只需要编写一个方法,该方法会创建所需类型的实例,然后给该方法添加@Bean注解

@Configuration
public class CarConfig2 {

    @Bean
    public IEngine setIEngine() 
    {
        return new AudiEngine();
    }
}

至于该方法中如何产生bean实例,只受java语言的限制。

借助javaConfig实现注入

@Configuration
public class CarConfig2 {

    @Bean
    public IEngine setIEngine() 
    {
        return new AudiEngine();
    }
    
    @Bean
    public ICar getCar() 
    {
        return new AudiCar(setIEngine());
    }
}

总之,使用javaConfig配置bean和装配依赖关注两点就好:一是使用@Configuration 注解创建配置类,二是使用@Bean注解完成bean的创建逻辑和依赖的注入。

使用xml来装配bean

在spring配置文件中使用<bean>元素声明bean:

    <bean id="iEngine" class="springdemo.test1.entity.impl.AudiEngine"/>

用xml方式声明bean的一些特征:

  • 自己不用直接负责创建bean实例了,在基于javaConfig的配置中,需要自行创建bean,当spring发现<bean>元素时,他会调用AudiEngine的默认构造器来创建。
  • 设置给cless属性的值是字符串,不能从编译期检查中知晓类型字符串是否正确。(不过目前IDE都能做检查,鼠标在字符串上,按住ctr看是否能跳转)

在xml中配置bean,只有一种可选方式,就是使用<bean>元素并指定class属性,spring会自行创建bean。

但是在xml中声明DI时,有两种依赖注入的方式:

  • 构造器注入
  • 属性注入

构造器注入

使用<constructor-arg ref=""/> 实现构造器注入

    <bean id="iEngine" class="springdemo.test1.entity.impl.AudiEngine"/>
    <bean id="iCar" class="springdemo.test1.entity.impl.AudiCar">
        <constructor-arg ref="iEngine"/>
    </bean>

使用spring3.0所引入的c-命名空间 实现构造器注入

<bean id="iCar" class="springdemo.test1.entity.impl.AudiCar" c:engine-ref="iEngine"/>

以“c:”开头,即命名空间前缀,接下来是要装配的构造器的参数名,在此之后是“-ref”,表明装配的是一个引用。

属性注入

    <bean id="iCar" class="springdemo.test1.entity.impl.AudiCar">
        <property name="engine" ref="iEngine"/>
    </bean>

同样也有“p-”命名空间属性注入风格:

<bean id="iCar" class="springdemo.test1.entity.impl.AudiCar" p:engine-ref="iEngine"/>

p-命名空间的约定同c-命名空间的约定一样。

注意:如果注入的不是bean引用,而是字面量。

<constructor-arg value=""/>       <bean c:_0="123"  c:_1="456"/>

<property name="engine" value=""/>   <bean p:_0="123"  p:_1="456"/>

导入和混合配置

首先要说的是自动装配时,它并不在意要装配的bean来自哪里,自动装配的时候会考虑spring容器中的所有bean,不管它是在javaConfig中或是在xml中声明的还是通过组件扫描获取到的。

如何在javaConfig中引用xml配置

@ImportResource("classpath:applicationContext-bean.xml")

另外javaConfig的配置也可以通过@Import(CarConfig.class)  注解进行整合

如何在xml中引用javaConfig配置

使用<bean>元素将javaConfig配置类声明为xml中的bean即可。

同样地,xml配置文件自身的整合可以使用元素<import resource=""/>

<import resource="engine.xml"/>
原文地址:https://www.cnblogs.com/happyone/p/10553132.html