Spring实战笔记二(bean的作用域、运行时注入、)

一、bean的作用域

        默认情况下,Spring应用上下文中所有bean都是以单例(singleton)的形式创建的。

        Spring定义的多种作用域,可以基于这些作用域创建bean,包括:

        1、单例(singleton):整个应用中,只创建bean的一个实例。

        2、原型(prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。

        3、会话(session):在web应用中,为每个会话创建一个bean实例。

        4、请求(request):web应用中,为每个请求创建一个bean实例。

想要改变bean的作用域,可以通过@Scope注解,它可以与@Component(注解扫描)或@Bean(JavaConfig)一起使用。

  • 单例和原型在注解扫描中的使用:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestScope {
}
  • 单例和原型在JavaConfig中的使用:
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public TestScope testScope(){
    return new TestScope();
}

其中ConfigurableBeanFactory的常量有两个:也可以直接填写字符串(不推荐,难免有手抖的时候,哈哈)

c951cd2d6420ef2080906ce4d4df5e321c8.jpg

  • 单例和原型在XML中的使用:
<bean id="testScope" class="com.caofanqi.bean.TestScope" scope="prototype" />
  • 会话和请求
@Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.INTERFACES) //会话作用域,接口代理模式
@Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.TARGET_CLASS) //会话作用域,CGLib代理模式
@Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.INTERFACES) //请求作用域,接口代理模式
@Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.TARGET_CLASS) //请求作用域,CGLib代理模式

        将value的值设置为SCOPE_SESSION,Spring会为Web应用的每个会话创建一个实例。这会创建多个实例,但是对于给定的会话只会创建一个实例,在当前会话,bean相当于单例的。

        ScopedProxyMode解决了将会话作用域的bean 注入到单例中遇到的问题,Spring在装载单例bean的时候,不会真正的注入会话模式的bean,而是出入一个会话作用域的代理bean,真正调用会话作用域的方法时,代理会进行解析,并将调用委托给真正的会话作用域bean。会话作用域的bean是接口的话,可以使用INTERFACES,如果是一个类的话需要使用TARGET_CLASS。

        请求作用域类似会话作用域。

在XML中,要使用Spring aop名称空间的一个新元素:

    <bean>元素的scope属性可以设置作用域,但是怎么指定代理模式呢?这需要Spring aop命名空间下的一个新元素<aop:scoped-proxy>(需要添加Spring aop的命名ko),它会告诉Spring为bean创建一个作用域代理。默认情况下,它会使用CGLib创建目标类的代理。我们可以将proxy-target-class属性设置为false,要求它进行基于接口的代理:

    <bean id="testScope" class="com.caofanqi.bean.TestScope" scope="session">
        <aop:scoped-proxy proxy-target-class="false"/>
    </bean>

二、运行时注入

        Spring提供了两种在运行时求值的方式:属性占位符、Spring表达式语言(SpEL)

    1、注入外部的值:声明属性源,通过Spring的Environment来检索属性

   ① 创建properties属性文件,如下:

title=zhangsan
price=23

    ②创建JavaConfig配置

@Configuration
@PropertySource("classpath:app.properties")  //属性文件位置
public class UserConfig {

    @Autowired
    private Environment environment;

    @Bean
    public User user(){
        //getProperty获得属性值
        return new User(environment.getProperty("title"),environment.getProperty("price",Double.class));
    }

}

    2、Environment的API

        获取属性的getProperty有四个重载的方法

String getProperty(String key);    //可能得到null
String getProperty(String key, String defaultValue); //当属性不存在时,可以取默认值
<T> T getProperty(String key, Class<T> targetType); //根据类型获取
<T> T getProperty(String key, Class<T> targetType, T defaultValue); //根据类型获取,取不到取默认值

       希望属性必须要定义:如果,key没有定义,竟会抛出异常

String getRequiredProperty(String key) throws IllegalStateException;

        检查某个属性是否存在

boolean containsProperty(String key);

    3、解析属性占位符:占位符的形式是 “${key} ”

    在XML中可以直接使用${key} 获取值,如:

    <context:property-placeholder location="app.properties"/>

    <bean id="user" class="com.com.caofanqi.User">
        <constructor-arg value="${title}" />
        <constructor-arg value="${price}" />
    </bean>

    如果使用注解扫描初始化,我们使用@Value注解,它的使用方式和@Autowired相似。

    public User( @Value("${title}")String title,  @Value("${price}")Double price) {
        this.title = title;
        this.price = price;
    }


4、SpEl,我用的不多

 

 

转载于:https://my.oschina.net/caofanqi/blog/3008333

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值