zoukankan      html  css  js  c++  java
  • 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"/>
  • 相关阅读:
    第3、4、5讲
    .NetCore使用EF5操作Oracle,解决列自增序列绑定不生效的问题
    ASP.NET Core 之 Identity 入门(一)
    ORACLE NLS_DATE_FORMAT设置
    ORA12514遇到了怎么排查问题出在哪
    Oracle特殊字符查询语句
    ORA00821: Specified value of sga_target 3072M is too small, needs to be at least 12896M
    如何定位哪些SQL产生了大量的Redo日志
    Oracle定位对阻塞的对象或锁信息
    Oracle Undo和Redo的关系,区别及相关查询
  • 原文地址:https://www.cnblogs.com/happyone/p/10553132.html
Copyright © 2011-2022 走看看