博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2018-11-18-spring-bean标签
阅读量:5882 次
发布时间:2019-06-19

本文共 3891 字,大约阅读时间需要 12 分钟。

创建方式

  1. 使用默认构造函数进行创建
    • 在spring的配置文件中使用bean标签,配以id与class属性的之后,并且没有其他属性与标签时。采用的就是默认无参构造进行创建对象,如果此时没有无参构造则无法创建对象。


  1. 使用普通工厂中的方法创建对象,也可以称之为使用某个类的方法创建对象,并存入spring容器
    简单地说就是id=unlimitedName01标签达到的功能就是在核心容器中获取key为unlimitedName01的value时,会先寻找到factory-bean的value指定的另一个bean标签,根据寻找到的这个标签,spring就会知道用_哪一个_工厂对象,而factory-method对应的value会让spring知道调用刚才寻找到工厂的_哪一个_方法!,所以在使用工厂的时候,spring最少配置两个bean标签。

  1. 使用静态工厂中的静态方法创建对象(或者说是使用某个类中的静态方法创建对象存入容器)

总结:除了配置文件的写法不同,以上三种方式在java代码中取出spring核心容器里面id对应的value方式完全相同。如取出静态工厂中生产的对象:

import cn.dx.service.impl.SaveServiceImpl;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SaveServlet {    public static void main(String[] args) {        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring-config.xml");        SaveServiceImpl staticFactory = classPathXmlApplicationContext.getBean("staticFactory", SaveServiceImpl.class);        staticFactory.save();    }}复制代码

以上的动态工厂与静态工厂中使用new造成耦合的原因是,为了演示方便工厂类都可以看做是jar包中的类,jar包中的类都是别人写的,我们都是不能改的,因为jar包中的类都是.class文件不是.java文件。当我们需要jar包中某个类的返回值存入spring容器中的时候就需要用到上面的2,3的方式。

工厂模式只能降低耦合,不能消除耦合


bean的作用范围

  • bean对象默认都是单例的
  • bean的scope属性可以用来指定bean的作用范围
    • 取值:1.singleton : 单例的(默认值) 2.prototype : 多例的 3. request : 作用于web应用的请求范围 4. session:作用于web应用的会话范围 5.global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,这个就是session。常用的为1,2项。

bean对象的生命周期

  • 单例对象
    • 出生:当spring核心容器创建时单例对象出生ClassPathXmlApplicationContext
    • 活着:只要容器还在对象就在
    • 死亡:容器销毁,对象消亡
    • 总结:单例对象的生命周期和容器相同

package cn.dx.servlet;import cn.dx.service.impl.SaveServiceImpl;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * 创建bean的三种方式 * 第一种方式:使用默认构造函数的方式进行创建 * */public class SaveServlet {    public static void main(String[] args) {        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring-config.xml");        SaveServiceImpl staticFactory = classPathXmlApplicationContext.getBean("serviceSave", SaveServiceImpl.class);        staticFactory.save();        //以为main线程执行结束后程序结束,还来不及调用容器的销毁方法,main方法就从内存中消失了,类似于线程直接中断,所以想到看到容器销毁需要        //手动调用容器的销毁方法        classPathXmlApplicationContext.close();    }}复制代码
  • 多例对象

多例对象有个很有趣的点,只是变更xml的scope配置,会发现,单例对象销毁容器会调用的destroy方法,在多例模式创建对象的时候却没有调用destroy方法。

  • 多例对象生命周期
    • 出生:当我们需要使用核心容器中的对象时,对象出生(这一点与BeanFactory创建多例对象的策略一致)
    • 活着:对象使用时一直存在
    • 死亡: GC垃圾回收之后(即没有任何栈内存空间指向的时候),spring并不知道对象是么时候用完,只能由GC进行对象销毁。

依赖注入 Dependency Injection

  • IOC的作用:削减(降低)程序(类与类)之间的依赖关系,所以既然是削减,那么依赖关系一定是存在的。耦合也叫做依赖关系。此时的依赖关系的管理就交给spring来维护
  • 什么叫做依赖关系呢?
    • 在当前类中需要用到其他类的对象时,由spring为我们提供,要想达到此种效果,只需要在spring的配置文件中告诉spring我们需要用哪个类就行了。
    • 依赖关系的维护,我们就称之为依赖注入
依赖注入的类型

一共有三类

  1. 基本类型和String
  2. 其他bean类型(在配置文件中或者注解配置过的bean)
  3. 复杂类型也叫集合类型
注入的方法-三种
  1. 使用构造函数提供
    • 其实核心为了弥补在一开始,使用控制反转创建对象的时候不能向构造函数传值的问题。
package cn.dx.service.impl;import cn.dx.service.SaveServiceInterface;import java.util.Date;public class SaveServiceImpl implements SaveServiceInterface {    private String x;    private Integer y;    private Date z;    public SaveServiceImpl(String x, Integer y, Date z) {        this.x = x;        this.y = y;        this.z = z;    }    @Override    public String toString() {        return "SaveServiceImpl{" +                "x='" + x + '\'' +                ", y=" + y +                ", z=" + z +                '}';    }    public void save() {        System.out.println("调用dao层");        System.out.println(this);    }    public void init(){        System.out.println("初始化生命周期被调用了");        System.out.println(this);    }    public void destroy(){        System.out.println("销毁方法被调用了");    }}复制代码

<constructor> 优势:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功
弊端:改变bean对象的实例化方式,是我们在创建对象时,如果用不到这些数据也必须提供。在实际开发中除了避无可避必须使用这种方式进行依赖注入的时候,其他时间是不采用这种方式的!而是采用set方式
2. 使用set方法提供

优势:创建对象没有明确的限制,可以直接注入(赋值使用)
弊端:如果有某个成员必须有值,则获取对象时有可能需要值得那个set方法没有执行
两个方法各有利弊(利弊相反)更常用(往往)的方式是set
3. 使用注解提供

复杂类型的注入(数组,List,Set,Map,Properties)

需要注意一点,name的值就是对应属性的名字。

结构相同的标签可以进行互换 所以我们只要记住一个List结构的标签与一个Map结构的标签就够了!

转载地址:http://dktix.baihongyu.com/

你可能感兴趣的文章
feign调用接口session丢失解决方案
查看>>
vuex所有核心概念完整解析State Getters Mutations Actions
查看>>
2.蟒蛇程序
查看>>
Linux常用命令收集
查看>>
UWP 页面跳转传值
查看>>
LeetCode - Add Binary
查看>>
图片格式问题分析报告
查看>>
RMAN_学习实验2_RMAN Duplicate复制数据库过程(案例)
查看>>
stl
查看>>
windows上同时安装两个版本的mysql数据库
查看>>
高性能Java科学与技术运算库Colt
查看>>
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
查看>>
自定义 URL Scheme 完全指南
查看>>
富文本编辑器
查看>>
centos yum遇到No more mirrors to try
查看>>
extern “C”的作用详解
查看>>
一小时包教会 —— webpack 入门指南
查看>>
查找最近的共有祖先元素
查看>>
使刚编辑的vim编辑器配置文件立即生效(实为自动生效)
查看>>
Struts2之文件上传与文件下载
查看>>