【spring】---spring的装配Bean方式

装配Bean方式

一、装配Bean方式汇总

Spring容器负责创建Bean并通过DI来协调对象间关系。
Bean如何进行装配,spring提供了下面三种基本方式+混合方式。
【spring】---spring的装配Bean方式
很多场景可以通过组件扫描和自动装配方式实现自动化装配Bean,但是,需要将第三方库的组件装配到应用中,是没有办法在它的类上添加@Component和@Autowired注解。此时只能采用显示装配Bean:Java显式和XML显式。

二、自动化装配Bean

实现自动化装配Bean,主要有两步骤:组件扫描自动装配
组件扫描(component scanning):Spring 会自动发现应用上下文中所创建的 bean【默认不开启】。
自动装配(autowiring):让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在 Spring 应用上下文中寻找匹配某个 bean 需求的其他 bean【可使用@Autowired 注解实现】。

2.1 组件扫描

Spring默认情况下,组件扫描是不启用的。我们还需要显式配置一下 Spring,从而命令它去寻找带有@Component、@Service注解的类,并为其创建bean。

@Configuration  --配置spring容器(应用上下文),将该类注入成Bean对象
@ComponentScan   ----在spring中启用组件扫描
public class scanConfig { 
}

—由于没有其他配置信息,那么@ComponentScan会默认扫描scanConfig类所在的包及包下的所有子包,查找带@Component、@Service注解的类。

2.2 自动装配

可以利用@Autowired注解帮忙寻找Bean及依赖的Bean信息。

2.3 具体实例讲解

下面以实际例子讲述@Component、@Service注解的类,怎样将Bean对象扫描到IOC容器,并且怎么装配使用。
—接口

public interface AutoBeanDesc {
    public String way();
}

—实现子类(@Component)

@Component
public class DescImpl implements AutoBeanDesc{
    @Override
    public String way() {
       return "DescImpl way .";
    }
}

—注解类(@Component)

@Component
public class AutowiConstructorDesc {
    private AutoBeanDesc autoBeanDesc;
    @Autowired //构造器上加注解
    public AutowiConstructorDesc(AutoBeanDesc autoBeanDesc){
        this.autoBeanDesc = autoBeanDesc;
    }
    public void desc1(){
        System.out.println(autoBeanDesc.way()+"AutowiConstructorDesc");
    }
}

—注解类(@Service)

@Service
public class AutowiSetterDesc {
    private AutoBeanDesc autoBeanDesc;
    /**
     * 将 required 属性设置为false 时,Spring 会尝试执行自动装配,
     * 但是如果没有匹配的 bean 的话,Spring 将会让这个 bean 处于未装配的状 态。
     */
    @Autowired(required=false) //用在Setter方法
    public void setCompactDisc(AutoBeanDesc autoBeanDesc){
        this.autoBeanDesc = autoBeanDesc;
    }
    public void desc1(){
        System.out.println(autoBeanDesc.way()+"AutowiSetterDesc");
    }
}

【spring】---spring的装配Bean方式

@Configuration
//@ComponentScan(basePackages ={"com.wwy.JavaBean.*"})
@ComponentScan(basePackages ={"com.wwy.JavaBean.AutoConfigBean"})
//@ComponentScan(basePackages ={"com.wwy.JavaBean.AutoConfigBean","com.wwy.JavaBean.XmlConfigBean"})
public class BeanConfig {
}

在JavaBean包下,有一个BeanConfig类,这个类没任何信息,@ComponentScan注解是spring启动组件扫描,@Configuration注解将BeanConfig类注入到Bean对象。
—Test验证

@ContextConfiguration(classes = BeanConfig.class) //指定bean注入的配置文件
//使用标准的JUnit @RunWith注释来告诉JUnit使用Spring TestRunner
@RunWith(SpringJUnit4ClassRunner.class)
public class test {
    @Autowired
    private AutoBeanDesc autoBeanDesc;
    @Autowired
    AutowiConstructorDesc autowiConstructorDesc;
    @Autowired
    AutowiSetterDesc autowiSetterDesc;
    @Test
    public void test() {
        System.out.println(autoBeanDesc.way());
        autowiConstructorDesc.desc1();
        autowiSetterDesc.desc1();
    }
}

三、Java显式装配Bean

【spring】---spring的装配Bean方式
—接口及实现子类

public interface JavaBeanDesc {
    public String way();
}
public class JavaBeanDescImpl implements JavaBeanDesc {
    @Override
    public String way() {
        return "JavaBeanDescImpl way.";
    }
}
public class JavaConstructorDesc {
    private JavaBeanDesc javaBeanDesc;
    public JavaConstructorDesc(JavaBeanDesc javaBeanDesc){
        this.javaBeanDesc = javaBeanDesc;
    }
    public String way(){
        return "JavaConstructorDesc "+javaBeanDesc.way();
    }
}

—JavaConfig类
@Configuration和@Bean将对应的类注入成Bean对象。

@Configuration //配置spring容器(应用上下文),将该类注入成Bean对象
public class JavaConfig {
    @Bean
    public JavaBeanDesc getJavaBeanDesc(){
        return new JavaBeanDescImpl();
    }
    @Bean
    public JavaConstructorDesc getJavaConstructorDesc(JavaBeanDesc desc){
        return new JavaConstructorDesc(desc);
    }
}
@Component
public class JavaBeanDescV2 {
    @Autowired
    JavaBeanDesc javaBeanDesc; //前面已经注入成Bean对象,所以直接装配使用
    public String way(){
        return "JavaBeanDescV2 "+javaBeanDesc.way();
    }
}

—测试方法

@Service
public class JavaBeanService {
    @Autowired
    JavaBeanDesc javaBeanDesc;
    @Autowired
    JavaConstructorDesc javaConstructorDesc;
    @Autowired
    JavaBeanDescV2 javaBeanDescV2;
      public void test(){
        System.out.println(javaBeanDesc.way());
        System.out.println(javaConstructorDesc.way());
        System.out.println(javaBeanDescV2.way());
    }
}

四、XML显式装配Bean

基于XML装配Bean两种方式:构造器注入、属性注入。对于强依赖,使用构造器注入;对于可选的属性使用属性注入。

4.1 构造器注入

【spring】---spring的装配Bean方式
----接口

public interface XmlBeanDesc {
    public void way();
}

----实现类

public class XmlDescImpl implements XmlBeanDesc {
    @Override
    public void way() {
        System.out.println("XmlDescImpl way .");
    }
}

–这个类将字面量注入到构造器中

public class XmlDescImplV2 implements XmlBeanDesc {
    private String title;
    private String name;
    private List<String> list;
    public XmlDescImplV2(String title,String name){
        this.title = title;
        this.name = name;
    }
    public XmlDescImplV2(String title,String name,List<String> list){
        this.title = title;
        this.name = name;
        this.list = list;
    }
    @Override
    public void way() {
        System.out.println("XmlDescImplV2 way . title:"+title+" name:"+name+
        " list:"+ JSON.toJSONString(list));
    }
}

—应用的实现类

public class XmlPlayer {
    private XmlBeanDesc xmlBeanDesc;
    public XmlPlayer(XmlBeanDesc xc){
        this.xmlBeanDesc = xc;
    }
    public void play(){
        xmlBeanDesc.way();
    }
}

—applicationContent.xml中配置

<!--使用XML装配Bean【使用构造器注入】-->
     <!--spirng发现这个Bean元素时,会调用XmlDescImpl的默认构造函数来创建Bean-->
<bean id="xmlDescImplV1" class="com.wwy.JavaBean.XmlConfigBean.XmlDescImpl"/>
     <!--spirng发现这个Bean元素时,会调用XmlDescImplV2的重写的构造函数来创建Bean-->
<bean id="xmlDescImplV2" class="com.wwy.JavaBean.XmlConfigBean.XmlDescImplV2">
    <constructor-arg value="title:hello"/>
    <constructor-arg value="name:wwy"/>
    <constructor-arg>
        <list>
            <value>list1</value>
            <value>list2</value>
        </list>
    </constructor-arg>
</bean>
     <!--以构造函数方式注入初始化xmlPlayerBean-->
<bean id="xmlPlayer" class="com.wwy.JavaBean.XmlConfigBean.XmlPlayer">
    <constructor-arg ref="xmlDescImplV2"></constructor-arg>
</bean>

—这样的话,测试使用

@Service
public class JavaBeanService {
    @Autowired
    XmlPlayer xmlPlayer;
    @PostConstruct
    public void test(){
        xmlPlayer.play();
    }
}

4.2 (setter)属性注入

public class XmlSetterPlayer {
    private XmlBeanDesc xmlBeanDesc;
    public void setXmlBeanDesc(XmlBeanDesc xc){ //setter属性方法
        this.xmlBeanDesc = xc;
    }
    public void play(){
        xmlBeanDesc.way();
    }
}

—applicationContent.xml中配置

<!--使用XML装配Bean【使用属性注入】-->
<bean id="xmlSetterPlayer" class="com.wwy.JavaBean.XmlConfigBean.XmlSetterPlayer">
    <property name="xmlBeanDesc" ref="xmlDescImplV2"></property>
</bean>

—这样的话,测试使用

@Service
public class JavaBeanService {
    @Autowired
    XmlSetterPlayer xmlSetterPlayer;
    @PostConstruct
    public void test(){
        xmlSetterPlayer.play();
    }
}

五、混合装配Bean

注意:下面的是参考其他博客的,具体的没尝试过。
(一)多个JavaConfig类进行配置:
在每个配置类上使用@Configuration注解;
在其中一个配置类上使用@Import(AnotherJavaConfigClass.class)即可实现导入;
【也可以在一个统一的JavaConfig类上使用@Import注解导入其他的所有JAVA配置类:@Import(AnotherJavaConfigClass.class, SomeElseJavaConfigClass.class)】
(二)在JavaConfig类中导入在XML中配置的Bean:
1.在Java配置类上增加一个@ImportResource注解:@ImportResource(“classpath:cd-config.xml”)
(三)在XML中导入另一个XML配置文件:
1.在目标XML文件中使用元素:<import resource=“cd-config.xml”
(四)没有一个直接的方法能将JavaConfig类导入到xml文件,间接的,通过声明一个配置累的Bean来导入:

上一篇:统计学习方法第十四章作业:聚类—层次聚类聚合/分裂算法、K_means聚类算法 代码实现


下一篇:CF2B The least round way