Spring Bean配置

Spring Bean管理

Spring的核心在于Ioc,我们上一篇已经提到了Ioc的概念,把对象的控制权较给容器来管理。在Spring中,凡是被Spring创建和管理的对象都叫做Bean。

Bean

Spring管理的Bean,一般是由你提供的配置来创建,如Java配置,注解配置,XML配置。在容器内部,这些Bean表现为BeanDefinition对象。

Bean的配置

基于XML的配置

在xml中,我们可以更了解Bean的配置,一个配置案例如下:


常见xml配置

分别解说各个参数的作用:

  • class: 要实例化的类。所谓的bean在内存中就是实例化后的对象。class指的是要实例化那个类。
  • name: Bean的名称,便于记忆
  • scope: 下面会提到
  • constructor arguments: 构造器参数
  • properties 属性
  • autowiring模式,Bean依赖其它Bean时候的模式
  • lazy-initialization 懒加载模式
  • initialization 初始化方法
  • destruction 销毁方法

直接拿一个XML注解的案例来说明:
还记得上一篇文章需要的几个类吗,这里我们再用一次。

  1. 准备好Java对象
public interface HelloWord {
    void sayHello();
}

public class HelloWordImpl1 implements HelloWord {
    @Override
    public void sayHello() {
        System.out.println("hello1");
    }
}

public class HelloWordImpl2 implements HelloWord {
    @Override
    public void sayHello() {
        System.out.println("hello2");
    }
}
  1. 根据不同的XML配置,获得不同的结果

2.1 scope的作用

scope为prototype时,每次从容器中获取bean,相应的对象都会重新实例化一次,也就是每次拿到的都是新创建的对象。
scope为singleton的时候,bean一直在容器中存在,直接容器销毁之前销毁,每次获取bean,获取到的是同一个bean


//准备好App文件

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        HelloWord helloWord2 = applicationContext.getBean(HelloWord.class);
        helloWord.sayHello();
        System.out.println(helloWord2);
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="prototype"/>
//运行结果
me.aihe.HelloWordImpl2@6a2bcfcb
me.aihe.HelloWordImpl2@4de8b406

<bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="singleton"/>
//运行结果
me.aihe.HelloWordImpl2@6d8a00e3
me.aihe.HelloWordImpl2@6d8a00e3

Spring默认bean的scope为singleton。

2.2 construct-arg参数
这个参数是构造bean对象的时候,提供构造参数
[图片上传失败...(image-d2cf54-1526781442058)]

  • ref指的是,当构造某个bean的时候,这个bean依赖其它的bean,使用ref来指向依赖的bean
  • type: 构造器参数中,精确的类型是什么,String或其它等等
  • index: 构造器参数具体的索引
//还是给一个简单运行的案例
//改造HelloWordImp2
public class HelloWordImpl2 implements HelloWord {

    String str;
    
    public HelloWordImpl2(String str) {
        this.str = str;
        System.out.println("实例化str:" + str);
    }

    public void sayHello() {
        System.out.println("hello2");
    }
}
//XML配置
   <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg type="java.lang.String" value="你好" />
    </bean>
     <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg index="0" value="你好" />
    </bean>
    <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg name="str" value="你好" />
    </bean>
    
// 以上三个bean只需要其中一个就好了,这里演示的是三个的运行结果都是一样的
//运行结果都是
实例化str:你好
me.aihe.HelloWordImpl2@d8355a8
me.aihe.HelloWordImpl2@d8355a8

2.3 property属性
property主要配置Java对象中有setter和getter方法的属性。

2.4 autowiring模式,保持默认就好,bean解析的方式,byType,byName

2.5 lazy-init赖加载模式
当设置为true的时候,只有在我们需要这个对象的时候,才会被实例化。

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        System.out.println("初始化applicationContext完成");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        System.out.println(helloWord);
    }
}


public class HelloWordImpl2 implements HelloWord {
    
    public HelloWordImpl2() {
        System.out.println("实例化中");
    }
    public void sayHello() {
        System.out.println("hello2");
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="true" />
// 运行结果
初始化applicationContext完成
实例化中
me.aihe.HelloWordImpl2@573f2bb1

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" />
//运行结果
实例化中
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3

可以看到,使用lay-init为true之后,在应用初始化完成后,只有再调用的时候才会实例化具体的bean。而设置为false则在初始化applicationContext的时候就实例化了。

2.6 init-method
在实例化该对象的后,调用此方法

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello"/>

//运行结果
实例化中
hello2
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3

2.7 destroy-method
容器销毁该bean的时候,调用此方法

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        System.out.println("初始化applicationContext完成");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        System.out.println(helloWord);
        ((ClassPathXmlApplicationContext) applicationContext).destroy();
    }
}

public class HelloWordImpl2 implements HelloWord {


    public HelloWordImpl2() {
        System.out.println("实例化中");
    }
    public void sayHello() {
        System.out.println("hello2");
    }

    public void sayGoodBye(){
        System.out.println("拜拜");
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello" destroy-method="sayGoodBye"/>

// 运行结果
实例化中
hello2
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3
拜拜

基于注解与基于Java的配置

了解了XML配置之后,注解的配置更加简单,关键的几个注解如下

  • @Bean, 可以指定name,init-method,destroy-method,autowire

  • @Lazy 指定bean是否要懒加载

  • @Scope 指定scope

  • @Primary 当有多个bean类型相同的时候,指定优先使用带有@primary的bean,有多个@primary标记类型相同的bean的时候,会报错

  • @Component,@controller,@Service,@Reposotory 标记某个对象为bean

Bean的扫描

在XML配置中

// 开启注解配置
<context:annotation-config />
// 扫描bean所在的包
<context:component-scan base-package="me.aihe" />

Java配置

@ComponentScan(value = "me.aihe")

小结

这篇文章主要讲了Bean的常见配置,Bean的配置还有更深入的内容,等待我们去探索。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 6,713评论 2 22
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,803评论 6 342
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,392评论 1 92
  • ‌时时计划与记录–必须隔离环境坚持番茄钟工作与休息–培养耐心最重要的是要提升你对时间的感知能力 发现做不到时时 争...
    黄冉欣阅读 97评论 0 0