• 最小化Spring XML配置


    Spring提供两种技巧,可以帮助我们减少XML的配置数量。

    1.自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系。

    2.自动检测(autodiscovery)比自动装配更进一步,让Spring自动识别哪些类需要被配置成Spring Bean,从而减少对<bean>元素的使用。

    一、4种类型的自动装配

    1.byName,把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中。如果没有跟属性的名字相匹配的Bean,则该属性不进行装配。

    <bean id="instrument" class="cn.edu.stu.springidol.Saxphone" />
        
    <bean id="kenny2" class="cn.edu.stu.springidol.Instrumentalist" autowire="byName">
        <property name="song" value="Jingle Bells" />
    </bean>

    Saxphone的id属性与kenny的instrument属性的名字是一样的。

    缺点:需要假设Bean的名字与其他Bean的属性名字一样。

    2.byType,把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中,如果没有跟属性的类型相匹配的Bean,则该属性不被装配。

    <bean id="saxphone" class="cn.edu.stu.springidol.Saxphone" />
    
    <bean id="kenny2" class="cn.edu.stu.springidol.Instrumentalist" autowire="byType">
        <property name="song" value="Jingle Bells" />
    </bean>

     缺点:如果Spring寻找到多个Bean的类型与需要自动装配的类型都相匹配,Spring不会猜测哪一个Bean更适合装配,而是抛出一个异常,所以应用只允许存在一个Bean与需要自动装配的属性类型相匹配。

    两种解决方法可以解决byType带来的歧义:

    1.声明候选Bean的primary属性为true,但默认的primary属性是true的,所以必须声明除候选Bean外的其他非候选Bean的primary属性为false

    2.设置在自动装配时被忽略的Bean,autowire-candidate属性为false,要求Spring在自动装配时,忽略Bean作为候选Bean

    3.constructor,把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器的对应入参中。

    如果通过构造器注入来配置Bean,可以移除<constructor-arg>元素

    <bean id="duke2" class="cn.edu.stu.springidol.PoeticJuggler" autowire="constructor" />

    缺点:当发现多个Bean匹配构造器入参,Spring不会猜测哪一个更适合,此外,如果一个类有多个构造器都满足自动装配条件,Spring也不会猜测哪一个更适合。

    4.autodetect,首先尝试使用constructor进行自动装配,如果失败,再尝试使用byType进行自动装配。

    2.5之前还可以使用,3.0之后就没有了。

    默认自动装配:

    在<beans>上增加一个default-autowire属性,作用于Spring配置文件的所有Bean,可以用<bean>元素的autowire属性覆盖<beans>的默认自动装配策略。

    还可以使用混合使用自动装配和显示装配。

    二、使用注解装配

    Spring容器默认禁用注解装配,启用方式的使用context命名空间配置中的<context:annotation-config>元素。

    <?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"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <context:annotation-config />
    
    </beans>

    1.使用@Autowired

    不仅可以标注setter方法,还可标注需要自动装配Bean引用的任意方法,构造器,属性。

    可选的自动装配,属性不一定非要装配,null值也可以接受,通过设置required属性为false来配置自动装配是可选的。但是当使用构造器装配时,只有一个构造器可以将required属性设置为true,其他使用@Autowired注解标注的构造器只能将required设置为false,当使用@Autowired标注多个构造器,Spring选择满足装配条件中入参最多的那个。

    限定歧义性的依赖,可能有至少两个Bean完全满足装配条件,如何选择。

    使用Qualifier("beanID")明确指定注入ID为beanID的Bean

    或者:

    XML声明Bean

    <bean id="saxphone" class="cn.edu.stu.springidol.Saxphone">
        <qualifier value="stringed" />
    </bean>
    @Autowired
    @Qualifier("stringed")
    private Instrument instrument;

    还可以创建自定义的限定器。

    2.@Inject实现基于标准的自动装配

    可以用来自动装配属性、方法和构造器,与@Autowired不同的是,没有required属性。

    限定@Inject所标注的属性,使用@Named("beanID")

    创建自定义限定器,与@Autowired类似。

    在注解中使用表达式:

    @Value("Eruption")
    private String song;
    
    @Value("#{systemProperties.myFavoriteSong}")
    private String song;

    三、自动检测Bean

    <context:annotation-config>有助于消除<property>和<constructor-arg>元素,但仍需要使用<bean>显示定义Bean。

    <context:component-scan>除了完成<context:annotation-config>一样的工作,还允许spring自动检测Bean和定义Bean,这意味着不使用<bean>元素。

    <?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"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <context:component-scan 
            base-package="cn.edu.stu.springidol">
        </context:component-scan>
    
    </beans>

    <context:component-scan>会扫描指定的包及其所有子包,并找出能够自动注册为Spring的类。

    如何知道哪些类需要注册为Spring Bean?

    1.为自动检测标注Bean

    <context:component-scan>会查找使用构造型注解所标注的类

    i.@Component,通用的构造性注解,标识该类为Spring组件

    ii.@Controller,标识该类定义为Spring MVC controller

    iii.@Repository,标识该类定义为数据仓库

    iv.@Service,标识该类定义为服务

    v.使用@Component标注的任意自定义注解

    import org.springframework.stereotype.Component;
    
    @Component
    public class Guitar implements Instrument {
    
        @Override
        public void play() {
            System.out.println("Strum Strum Strum");
    
        }
    
    }

    Guitar会被自动地注册为Spring Bean,ID默认为无限定类名,这里是guitar,可以通过@Component("anotherName")显式命名ID。

    2.过滤组件扫描

    使用<context:include-filter>告知哪些类需要注册为Spring Bean,使用<context:exclude-filter>告知哪些类不需要注册为Spring Bean。

    5种过滤器类型:

    i.annotaion,使用指定注解所标注的类,通过expression属性指定要扫描的注解

    ii.assignable,扫描派生于expression属性指定类型的那些类

    iii.aspject,扫描expression属性所指定的AspectJ表达式所匹配的那些类

    iv.custom,使用自定义的org.springframework.core.type.TypeFilter实现类,该类由expression指定

    v.regex,扫描类的名称与expression属性所指定的正则表达式所匹配的那些类

    四、使用Spring基于Java的配置(为了不使用XML为目的)

    1.创建基于Java的配置

    首先启动<context:component-scan>,这需要少量的XML配置,

    <context:component-scan>会自动注册那些使用某种构造型注解所标注的Bean,但它也会自动加载使用@Configuration注解所标注的类。

    2.定义一个配置类(类放在base-package指定的包下)

    @Configuration
    public class SpringIdolConfig {
        
    }

    3.声明一个简单Bean

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SpringIdolConfig {
        @Bean
        public Performer duke() {
            return new Juggler();
        }
    }

    使用@Bean注解标注的duke方法会告知Spring我们希望该方法定义的Bean被注册进Spring的应用上下文中,因此,在其他Bean的声明方法中引用这个方法,Spring会拦截该方法的调用,并尝试在应用上下文中查找该Bean,而不是让方法创建一个新的实例。

  • 相关阅读:
    Flink CEP实例及基础应用
    seata 分布式事务
    skywalking 分布式链路追踪
    datax 离线数据同步工具
    rocketmq 消息队列
    Nacos 服务注册
    跨站(cross-site)、跨域(cross-origin)、SameSite与XMLHttpRequest.withCredentials
    读写二进制文件与文本文件
    WPF中通过双击编辑DataGrid中Cell(附源码)
    记一次XML文件读取优化
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5796418.html
Copyright © 2020-2023  润新知