Spring--基础-- IOC(四)

一、IOC(控制翻转)

  1. 什么是 IOC?
    把对象的创建、初始化、销毁等工作交给 Spring 容器来做。
  2. 创建对象的方式
    Bean类:
@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    public User(){
       System.out.print("用户构造器\n");
    }
}

A. 构造器

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    public User(){
       System.out.print("用户构造器\n");
    }
}

配置:

 <!--构造注入-->
    <bean id="user0" class="com.neuedu.entity.User">
        <property name="username" value="测试一下spring"/>
    </bean>

B. 静态工厂

public class UserStaticFactory {
    public static User getInstance() {
        User user=new User();
        user.setUsername("张三");
       return user;
    }
}

配置:

    <!--静态工厂注入-->
    <bean id="user1" class="com.neuedu.factory.UserStaticFactory" factory-method="getInstance">
    </bean>

C. 实例工厂

public class UserInstanceFactory {
    public User getInstance(){
        User user=new User();
        user.setUsername("张三");
        return user;
    }
}

配置:

    <!--实例工厂注入-->
    <bean id="userFactory" class="com.neuedu.factory.UserInstanceFactory">
    </bean>
    <bean id="user2" factory-bean="userFactory" factory-method="getInstance"> 
   </bean>
  1. 别名
<bean id="userFactory"
class="com.neuedu.UserInstanceFactory"></bean>
<!--
factory-bean:指向工厂bean
factory-method:指向工厂方法
-->
<bean id="user" factory-bean="userFactory" factorymethod="getInstance"></bean>
<alias name="user" alias="abc"/>
给对象 user 起个别名叫张三。
测试:
@Test
public void testTest() {
User user = (User)applicationContext.getBean("abc");
user.setUserName("XXX");
user.output();
}

二、对象的创建时机

当 spring 容器启动的时候创建对象便会根据 bean 配置创建相应对象,有几个 bean 就会创建几次对象。

<bean id="user" lazy-init="default" class="com.neuedu.User"></bean>

lazy-init 属性:
Default 相当于 false
在 spring 容器启动的时候,创建对象
True 在 context.getBean 时创建对象;
False 在 spring 容器启动的时候创建对象;
如果把 lazy-init 设置为 true,则当 spring 容器启动的时候,检测不到任何错误,这样会存在很大的安全性隐患,所以一般情况下应该设置 lazy-init 为 default/false。但是如果一个 bean中有一个属性,该属性含有大量的数据,这个时候不希望该 bean 过早的停留在内存中。
这个时候需要用到 lazy-init 为 true。

三、对象的 scope 作用域

默认情况(scope=singleton)

@Test
public void testTest() {
User user1 = (User)applicationContext.getBean("user");
User user2 = (User)applicationContext.getBean("user");
System.out.println(user1);
System.out.println(user2);
}

结果:
构造器方式创建对象

com.neuedu.User@52a86356
com.neuedu.User@52a86356

在默认情况下放入到 spring 中的 bean 是单例的
将来 service 层和 dao 层所有的类将放入到 spring 容器中,所以默认情况下这两个层的
类的实例都是单例的,所以不能把数据声明到属性中。如果声明在属性中,将会成为共享的。
Scope 为 prototype

<bean id="user" scope="prototype" class="com.neuedu.User"></bean>

测试:

@Test
public void testTest() {
User user1 = (User)applicationContext.getBean("user");
User user2 = (User)applicationContext.getBean("user");
System.out.println(user1);
System.out.println(user2);
}

结果:
构造器方式创建对象
构造器方式创建对象

com.neuedu.User@544fe44c
com.neuedu.User@31610302

四、创建时机和 scope 的结合

  1. Scope 为 prototype时,只有在context.getBean 时创建对象。
  2. Scope 为 prototype,lazy-init 为 true,在 context.getBean 时创建对象。
  3. Scopse 为 prototype,lazy-init 为 false在 context.getBean 时创建对象,lazy-init 为 false 失效;
  4. 当 scpose 为 prototype 时,始终在 context.getBean 时创建对象。
 <!--构造注入-->
    <bean id="user" scope="prototype" class="com.neuedu.entity.User">
    </bean>

测试:

 User user = (User) applicationContext.getBean("user");

五、Init 和 destroy

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    public User(){
       System.out.print("用户构造器\n");
    }
    public void init(){
        System.out.print("初始化方法\n");
    }
    public void destory(){
        System.out.print("销毁方法\n");
    }
}

配置:

<bean id="user" init-method="init" destroy-method="destory" class="com.neuedu.entity.User">
        <property name="username" value="测试一下spring"/>
</bean>

测试:

   @Test
    public void testSpring() {
        //关闭Spring容器
        ClassPathXmlApplicationContext
                application=(ClassPathXmlApplicationContext)applicationContext;
        application.close();
    }

说明:
1、 init 方法是由 spring 内部执行的;
2、 只有当 spring 容器关闭以后才能执行 destroy 方法,spring 容器一般情况下是不会关闭的。只有当 web 容器销毁掉的时候才可能关闭掉,所以只要一个对象在 spring容器中,在 spring 容器关闭之前,会一直保留。
3、 如果一个 bean 的配置是 scope 为”prototype”,则 spring 容器不负责销毁。

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

推荐阅读更多精彩内容