Spring(学习笔记)基础篇-Bean的作用域以及工厂Bean!

重点标识

bean的作用域,简单来说,就是bean起作用的范围,
常见的有:
prototype:也叫原型作用域,每次请求都会获取一个新的bean。
singleton:相当于单例模式,即Ioc容器中只存在一个实例,怎么获取都是它。
不常见的有:
session(会话级别), web项目中比较常见,一般登录后就会产生,然后一直持续到超时或者注销,在这期间,共用一个bean。
request(一次请求创建一个实例),http每次请求都会产生一个新的bean。
applicaton,全局作用域 (与Spring容器进行绑定,一个Spring容器,一个bean,一般作为全局配置,系统初始化时,进行加载,当然在一些特殊的web工程中,是有可能多个Spring容器的,也会存在多个application)。
websocket(消息会话)在整个消息连接期间,共享一个bean,了解到的,一般用于聊天室之类的。

有一些不能直接使用的bean,注入到Spring容器中,我们可以使用工厂bean来搞定,如okhttp;

singleton(单例)

注入Spring容器中,如果不增加额外的说明,一般就是单例的,如下:

public class User {

    private String id;

    private String username;
    private String address;
}    

    <bean class="org.tongzhou.model.User" id="user" scope="singleton"/>
    public static void main(String[] args) {

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user");
        Object user2 = context.getBean("user");

        System.out.println(user2 == user);
    }

结果之然是true;
如果我们改了scope,则又是另一种结果了。

prototype (多实例)

  <bean class="org.tongzhou.model.User" id="user" scope="prototype"/>

调用main方法,结果就是false。

okhttp

我们可以看到,new 一个okhttp是没有set方法,让我们填入参数的,这种情况下,我们又想将这个第三方的工具类交给Spring容器去进行管理,那我们可以这么做。

静态工厂


public class OkHttpClientStaticFactory {

    private  static  OkHttpClient client;

    static {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.setConnectTimeout$okhttp(10000);
        builder.setReadTimeout$okhttp(10000);

        client = builder.build();
    }

    public static OkHttpClient getInstances(){

        return client;
    }
}

xml配置

这里需要注意的是,这里注入的是OkhttpClient返回的实例而不是OkHttpClientStaticFactory

  <bean class="org.tongzhou.factory.OkHttpClientStaticFactory" factory-method="getInstances"/>

测试方法

public static void main(String[] args) {

        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        OkHttpClient bean = classPathXmlApplicationContext.getBean(OkHttpClient.class);
        Request build = new Request.Builder().get().url("https://www.baidu.com").build();
        Call call = bean.newCall(build);
        call.enqueue(new Callback() {
            /**
             * 请求失败的回调
             * @param call
             * @param e
             */
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

            }

            /**
             * 请求成功的回调
             * @param call
             * @param response
             * @throws IOException
             */
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {

                System.out.println(response.body().string());
            }
        });
    }

实例工厂

创建一个实例,加载的时候调用!


public class OkHttpClientFactory {

    OkHttpClient okHttpClient;

    public OkHttpClient getOkHttpClient(){

        if(okHttpClient == null){

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.setConnectTimeout$okhttp(10000);
            builder.setReadTimeout$okhttp(10000);

            okHttpClient = builder.build();
        }

        return okHttpClient;
    }
}

这里需要注意,必须要取到实例之后,才能调用。

 <bean class="org.tongzhou.factory.OkHttpClientFactory" id="clientFactory"/>
    <bean id="client" factory-bean="clientFactory"  factory-method="getOkHttpClient"/>
public static void main(String[] args) {

        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        OkHttpClient bean = classPathXmlApplicationContext.getBean("client",OkHttpClient.class);

FactoryBean(推荐)

实现FactoryBean接口,这里我们可以进去看一下,实际上getObject()方法体,getObjectType() 返回类型,重点是isSingleton(),默认是true,也就是单例,但实际上,如果你返回一个false,他也不一定是prototype ,因为除此之外,还有其他的作用域,这里需要注意下;
在这里插入图片描述

ok 我们接下来看代码实现


public class OkHttpClientFactoryBean implements FactoryBean<OkHttpClient> {
    @Override
    public OkHttpClient getObject() throws Exception {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.setConnectTimeout$okhttp(10000);
        builder.setReadTimeout$okhttp(10000);

        return builder.build();
    }

    @Override
    public Class<?> getObjectType() {
        return OkHttpClient.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}


这里要注意,这边注册到spring容器的,是它的getObject方法,如果想要获得它本身,则可以这样获取。

  <bean class="org.tongzhou.factory.OkHttpClientFactoryBean" id="client2"/>
  public static void main(String[] args) {

        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object bean = classPathXmlApplicationContext.getBean("client2");
        //获得他本身所代表的实例
        Object bean2 = classPathXmlApplicationContext.getBean("&client2");
        System.out.println(bean);
        System.out.println(bean2);
    }
    ``
    
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值