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 层的服务

  @Repository 标注 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>
    

posted on 2020-01-16 17:15  灰马非马  阅读(347)  评论(0编辑  收藏  举报

导航