zoukankan      html  css  js  c++  java
  • Spring的Bean配置和装配

    Spring的Bean配置和装配


    每个bean定义只生成一个对象实例,每次getBean请求获得的都是此实例
    spring单例默认是饿汉模式

    XML配置

    配置Bean——setter方法设置属性

    <!-- 无属性bean -->
    <!-- 如果不指明id,则会用全限定类名加上#序号命名 -->
    <bean id="address" class="com.spring.xmlBean.Address"></bean>
    <!-- 普通属性bean -->
    <bean id="address" class="com.spring.xmlBean.Address">
            <property name="city" value="日照"></property>
            <property name="province" value="山东"></property>
    </bean>
    <!-- 通过ref引用其他bean作为属性 -->
    <bean id="person" class="com.spring.xmlBean.Person">
            <property name="name" value="Little-Koala"></property>
            <property name="age" value="18"></property>
            <property name="address" ref="address"></property>
    </bean>
    <!-- 属性为集合的bean -->
    <bean id="complexAssembly"class="com.ssm.chapter10.pojo.ComplexAssembly">
            <property name="id" value="1"/>
            <property name="list">
                <list>
                    <value>value-list-1</value>
                    <value>value-list-2</value>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key="key1" value="value-key-1"/>
                    <entry key="key2" value="value-key-2"/>
                </map>
            </property>
            <property name="props">
                <props>
                    <prop key="prop1">value-prop-1</prop>
                    <prop key="prop2">value-prop-2</prop>
                </props>
            </property>
            <property name="set">
                <set>
                    <value>value-set-1</value>
                    <value>value-set-2</value>
                </set>
            </property>
            <property name="array">
                <array>
                    <value>value-array-1</value>
                    <value>value-array-2</value>
                </array>
            </property>
        <!-- 集合的涉及对象的bean装载 -->
        	<property name="list2">
                <list>
                    <ref bean="role1"/>
                    <ref bean="role2"/>
                </list>
            </property>
        	<property name="map2">
                <map>
                    <entry key-ref="role1" value-ref="user1"/>
                    <entry key-ref="role2" value-ref="user2"/>
                </map>
            </property>
            <property name="set2">
                <set>
                    <ref bean="role1"/>
                    <ref bean="role2"/>
                </set>
            </property>
        </bean>
    

    配置Bean——构造器初始化

    <!-- 构造器普通参数 -->
    <bean id="address" class="com.spring.xmlBean.Address">
            <constructor-arg name="city" value="日照"></constructor-arg>
            <constructor-arg name="province" value="山东"></constructor-arg>
    </bean>
     <!-- 构造器对象参数 -->
    <bean id="person" class="com.spring.xmlBean.Person">
            <constructor-arg name="name" value="Little-Koala"></constructor-arg>
            <constructor-arg name="age" value="18"></constructor-arg>
            <constructor-arg name="address" ref="address"></constructor-arg>
    </bean>
    <!-- 构造器也可以配置集合作为参数,格式类似与setter方法,这里不再列举 -->
    

    命名空间

    要使用命名空间需要在头部xml加入:

    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:c="http://www.springframework.org/schema/c"
    

    装配bean引用与装配字面量的唯一区别在于是否带有“-ref”后缀。如果没有“-ref”后缀的话,所装配的就是字面量

    <bean id="hello2" class="com.app.Hello" p:p1="v1" p:p2="v2" p:world-ref="world"/>
    <bean id="hello2" class="com.app.Hello" c:arg1="c_arg1" c:arg2="2" c:arg3-ref="world"/>
    

    命名空间的属性无法实现装配集合的功能,解决方法就是util命名空间

    <util:list id="userList" value-type="java.lang.String">
    		<value>张三</value>
    		<value>李四</value>
    		<value>王五</value>
    </util:list>
    <!-- 配置一个Map集合 -->
    <util:map id="userMap">
            <entry key="user1" value-ref="user" />
            <entry key="user2">
                <!-- 配置一个内部Bean -->
                <bean class="io.shuqi.ssh.spring.util.User">
                    <property name="userAge" value="12" />
                    <property name="userName" value="小张" />
                </bean>
            </entry>
    </util:map>
    <!-- 命名空间中引用util命名空间 -->
    <bean id="hello2" class="com.app.Hello" c:arg1="c_arg1" c:arg2="2" c:arg3-ref="list"/>
    

    xml配置扫描路径

    <!-- 扫描的基本包路径 -->
    	<!-- 是否激活属性注入注解 -->
    	<!-- Bean的ID策略生成器 -->
    	<!-- 对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行 -->
    	<!-- scope解析器 ,与scoped-proxy只能同时配置一个 -->
    	<!-- scope代理,与scope-resolver只能同时配置一个 -->
    	<!-- 是否使用默认的过滤器,默认值true -->
    	<context:component-scan base-package="com.wjx.betalot"
    		annotation-config="true"
    		name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"
    		resource-pattern="**/*.class"
    		scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver"
    		scoped-proxy="no" use-default-filters="false">
    		
    		<!-- 注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖 -->
    		<!-- annotation是对注解进行扫描 -->
    		<context:include-filter type="annotation"
    			expression="org.springframework.stereotype.Component" />
    		<!-- assignable是对类或接口进行扫描 -->
    		<context:include-filter type="assignable"
    			expression="com.wjx.betalot.performer.Performer" />
    		<context:include-filter type="assignable"
    			expression="com.wjx.betalot.performer.impl.Sonnet" />
    
    		<!-- 注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除 -->
    		<context:exclude-filter type="annotation"
    			expression="org.springframework.stereotype.Controller" />
    		<context:exclude-filter type="assignable"
    			expression="com.wjx.betalot.performer.impl.RainPoem" />
    		<context:exclude-filter type="regex"
    			expression=".service.*" />
    	</context:component-scan>
    

    代码通过读取xml获取bean

    
    ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("SpringBean.xml");
    TestCollection test=applicationContext.getBean("test",TestCollection.class); 
    
    
    Java配置

    • JavaConfig配置主要用于第三方工具类的bean初始化
    • 创建javaConfig类的关键在于为其添加@Configuration注解,这个注解表明它是一个配置类,该类包含在spring应用上下文中如何创建bean的细节

    在config类中配置Bean

    在Configuration注解中配置的bean主要是第三方工具类的初始化,步骤一般是new一个新的实例,然后通过set方法设置参数,然后返回该实例对象。

     @Bean // 实际使用的redisTemplate,可以直接注入到代码中,直接操作redis
        public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
            RedisSerializer<?> stringSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringSerializer);
            redisTemplate.setValueSerializer(stringSerializer);
            redisTemplate.setHashKeySerializer(stringSerializer);
            redisTemplate.setHashValueSerializer(stringSerializer);
            redisTemplate.setDefaultSerializer(stringSerializer);
            redisTemplate.setConnectionFactory(lettuceConnectionFactory);
            return redisTemplate;
        }
    

    JavaConfig注解说明

    Import注解的作用就是把多个配置组合在一起,然后通过ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)配置类读取bean的时候,统一从一个配置类里面获取

    • Import注解
      • @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
    • ImportResource注解
      • ImportResource和@Value进行资源文件读取
    • PropertySource 注解
      • Spring框架提供了PropertySource注解,目的是加载指定的属性文件
    • Profile注解
      • @profile注解是spring提供的一个用来标明当前运行环境的注解

    @Configuration、@Bean、@DependsOn、@Primary、@Lazy、@Import、@ImportResource、@Value

    自动发现装配

    配置Bean

    • 注解解析

      @Component 是通用标注

      @Controller 标注 web 控制器

      @Service 标注 Servicec 层的服务

      @Respository 标注 DAO 层的数据访问

    • 注解配置Bean
      • 使用注解配置bean时候,并没有指定bean的id,那么Spring帮我们创建 bean时候会给一个默认的id,id为类名首字母小写
      • 当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致
    @Service("beanFactory") 
    public class BeanFactroyImpl implements BeanFactory {
    
      @Autowired
      private UserRepository userRepository;
    }
    @Component
    public class LogonService {}
    

    自动装载

    • @Autowired

      @Autowired默认是按照byType进行注入的,但是当byType方式找到了多个符合的bean,又是怎么处理的?如果发现找到多个bean,则又按照byName方式比对(默认是该类的类名,且首字母是小写),如果还有多个,则报出异常

    • @Qualifier

      如果容器中有一个以上匹配的Bean,则可以通过@Qualifier注解限定Bean的名称.@Qualifier("bmwCar")

    • @Resource

      (这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

    混合配置

    * @Import注解,将两个配置类组合在一起,组成一个新的配置类
    @Configuration
    @Import({CDConfig.class,CDPlayerConfig.class})
    public class SoundSystemConfig {
    }
    
    • @ImportSource注解,将配置文件和XML共同的加载到Spring文件中

      @Configuration
        @ComponentScan
        @Import(CDConfig.class)
        @ImportResource("classpath:applicationContext.xml")
        public class CDPlayerConfig { 
          @Bean
          public CDPlayer compactDisc(CompactDisc compactDisc){
            return new CDPlayer(compactDisc);
          }
        }
      
    • XML 中引入JavaConfig

      <?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:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!-- spring配置文件中<beans>的子元素<bean>,每个子元素定义一个Bean,并描述了Bean该如何被装配到Spring容器中。 -->
        <!-- 加载CDConfig配置文件,获取一个光盘对象实例 -->
        <bean class="soundsystem.CDConfig" />
        <bean id="cdPlayer"
              class="soundsystem.CDPlayer"
              c:cd-ref="compactDisc" />
      </beans>
      

  • 相关阅读:
    JSP总结1
    EL总结2-域
    EL总结1
    getRealPath和getContextPath
    mybatis获取参数数值的两个方式
    进程与线程区别与联系
    进程间通信和线程间通信的区别
    STRLEN
    二叉树数据结构和算法
    TYPDEF使用注意部分
  • 原文地址:https://www.cnblogs.com/yanghanwen/p/12202321.html
Copyright © 2011-2022 走看看