原创

面试总结

1、String、StringBuffer、StringBuider的区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
  String最慢的原因:
  String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
       而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
  2. 再来说线程安全
  在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。
  如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
  3. 总结一下
  String:适用于少量的字符串操作的情况
  StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

2、ArrayList和LinkedList有什么区别?

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 (LinkedList是双向链表,有next也有previous)
     2.对于随机访问getset,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
     3.对于新增和删除操作addremove,LinedList比较占优势,因为ArrayList要移动数据。
```

1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。


**3int 和interger的区别?**

1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0。


**4、什么是值传递和引用传递?**

值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。
引用传递:(形式参数类型是引用数据类型参数):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。


**5、&和&&的区别?**

&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。


**6、什么是cookie? session和cookie有什么区别?**

1、Cookie 在客户端(浏览器),Session 在服务器端。
2、Cookie的安全性一般,他人可通过分析存放在本地的Cookie并进行Cookie欺骗。在安全性第一的前提下,选择Session更优。重要交互信息比如权限等就要放在Session中,一般的信息记录放Cookie就好了。
3、单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie。
4、Session 可以放在 文件、数据库或内存中,比如在使用Node时将Session保存在redis中。由于一定时间内它是保存在服务器上的,当访问增多时,会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用Cookie。
5、Session 的运行依赖Session ID,而 Session ID 是存在 Cookie 中的,也就是说,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)。
6、用户验证这种场合一般会用 Session。因此,维持一个会话的核心就是客户端的唯一标识,即Session ID。

**7、简述http请求的报文格式**

超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议。HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息。

  HTTP 请求报文

  HTTP 请求报文由请求行、请求头部、空行 和 请求包体 4 个部分组成,如下图所示
  ![file](http://wyz.wangyaozheng.top/wyz/article/20181225133429015.png)

下面对请求报文格式进行简单的分析:

  请求行:请求行由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;

  ● GET:当客户端要从服务器中读取某个资源时,使用GET 方法。GET 方法要求服务器将URL 定位的资源放在响应报文的数据部分,回送给客户端,即向服务器请求某个资源。使用GET 方法时,请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表URL 的结尾与请求参数的开始,传递参数长度受限制。例如,/index.jsp?id=100&op=bind。

  ● POST:当客户端给服务器提供信息较多时可以使用POST 方法,POST 方法向服务器提交数据,比如完成表单数据的提交,将数据提交给服务器处理。GET 一般用于获取/查询资源信息,POST 会附带用户数据,一般用于更新资源信息。POST 方法将请求参数封装在HTTP 请求数据中,以名称/值的形式出现,可以传输大量数据;

  请求头部:请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:

  ● User-Agent:产生请求的浏览器类型;

  ● Accept:客户端可识别的响应内容类型列表;星号 “ ” 用于按范围将类型分组,用 “ / ” 指示可接受全部类型,用“ type/ ”指示可接受 type 类型的所有子类型;

  ● Accept-Language:客户端可接受的自然语言;

  ● Accept-Encoding:客户端可接受的编码压缩格式;

  ● Accept-Charset:可接受的应答的字符集;

  ● Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;

  ● connection:连接方式(close 或 keepalive);

  ● Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;

  空行:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头;

  请求包体:请求包体不在 GET 方法中使用,而是在POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的是包体类型 Content-Type 和包体长度 Content-Length;

  HTTP 响应报文

  HTTP 响应报文由状态行、响应头部、空行 和 响应包体 4 个部分组成,如下图所示:

  下面对响应报文格式进行简单的分析:

  状态行:状态行由 HTTP 协议版本字段、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开;

  ● 状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类如下所示:

  1xx:表示服务器已接收了客户端请求,客户端可继续发送请求;

  2xx:表示服务器已成功接收到请求并进行处理;

  3xx:表示服务器要求客户端重定向;

  4xx:表示客户端的请求有非法内容;

  5xx:表示服务器未能正常处理客户端的请求而出现意外错误;

  ● 状态码描述文本有如下取值:

  200 OK:表示客户端请求成功;

  400 Bad Request:表示客户端请求有语法错误,不能被服务器所理解;

  401 Unauthonzed:表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用;

  403 Forbidden:表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因;

  404 Not Found:请求的资源不存在,例如,输入了错误的URL;

  500 Internal Server Error:表示服务器发生不可预期的错误,导致无法完成客户端的请求;

  503 Service Unavailable:表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常;

  响应头部:响应头可能包括:

  Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源;

  Server:Server 响应报头域包含了服务器用来处理请求的软件信息及其版本。它和 User-Agent 请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息。

  Vary:指示不可缓存的请求头列表;

  Connection:连接方式;

  对于请求来说:close(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,断开连接,不等待本次连接的后续请求了)。keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求);

  对于响应来说:close(连接已经关闭); keepalive(连接保持着,在等待本次连接的后续请求); Keep-Alive:如果浏览器请求保持连接,则该头部表明希望WEB 服务器保持连接多长时间(秒);例如:Keep-Alive:300;

  WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401 (未授权的)响应消息中,这个报头域和前面讲到的Authorization 请求报头域是相关的,当客户端收到 401 响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了Authorization 报头域的请求;

  空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有响应头部。

  响应包体:服务器返回给客户端的文本信息;

  HTTP 工作原理

  HTTP 协议采用请求/响应模型。客户端向服务器发送一个请求报文,服务器以一个状态作为响应。

  以下是 HTTP 请求/响应的步骤:

  ● 客户端连接到web服务器:HTTP 客户端与web服务器建立一个 TCP 连接;

  ● 客户端向服务器发起 HTTP 请求:通过已建立的TCP 连接,客户端向服务器发送一个请求报文;

  ● 服务器接收 HTTP 请求并返回 HTTP 响应:服务器解析请求,定位请求资源,服务器将资源副本写到 TCP 连接,由客户端读取;

  ● 释放 TCP 连接:若connection 模式为close,则服务器主动关闭TCP 连接,客户端被动关闭连接,释放TCP 连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;

  ● 客户端浏览器解析HTML内容:客户端将服务器响应的 html 文本解析并显示;

  例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:

  1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;

  2、解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立 TCP 连接;

  3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;

  4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;

  5、释放 TCP 连接;

  6、浏览器将该 html 文本并显示内容;

  HTTP 无状态性

  HTTP 协议是无状态的(stateless)。也就是说,同一个客户端第二次访问同一个服务器上的页面时,服务器无法知道这个客户端曾经访问过,服务器也无法分辨不同的客户端。HTTP 的无状态特性简化了服务器的设计,使服务器更容易支持大量并发的HTTP 请求。

  HTTP 持久连接

  HTTP1.0 使用的是非持久连接,主要缺点是客户端必须为每一个待请求的对象建立并维护一个新的连接,即每请求一个文档就要有两倍RTT 的开销。因为同一个页面可能存在多个对象,所以非持久连接可能使一个页面的下载变得十分缓慢,而且这种短连接增加了网络传输的负担。HTTP1.1 使用持久连接keepalive,所谓持久连接,就是服务器在发送响应后仍然在一段时间内保持这条连接,允许在同一个连接中存在多次数据请求和响应,即在持久连接情况下,服务器在发送完响应后并不关闭TCP 连接,而客户端可以通过这个连接继续请求其他对象。

  HTTP/1.1 协议的持久连接有两种方式:

  ● 非流水线方式:客户在收到前一个响应后才能发出下一个请求;

  ● 流水线方式:客户在收到 HTTP 的响应报文之前就能接着发送新的请求报文;

  最后给出一个具体例子:

  Remote Address:116.57.254.104:80 Request URL:http://hr.tencent.com/ Request Method:GET Status Code:200 OK Request Headers GET / HTTP/1.1 Host: hr.tencent.com Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8 User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4 Cookie: pgv_pvi=2098703360; PHPSESSID=bc7onl0dojbsatscsfv79pds77; pgv_info=ssid=s1454606128; pgv_pvid=926725350; ts_uid=4084753309 Response Header HTTP/1.1 200 OK Server: nginx Date: Mon, 26 Jan 2015 01:09:10 GMT Content-Type: text/html;charset=utf-8 Content-Length: 3631 Connection: keep-alive X-Powered-By: PHP/5.3.10 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Encoding: gzip

  从请求报文可以知道:

  GET / HTTP/1.1

  请求方法 GET 表示一个读取请求,将从服务器获得网页数据,/表示URL 的路径,URL 总是以/开头,/就表示首页,最后的HTTP/1.1 指示采用的 HTTP 协议版本是 1.1;请求域名如下所示:

  Host: hr.tencent.com

  响应报文如下:

  HTTP/1.1 200 OK

**8、构造器是否可以被重写?**
 首先,构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。 

又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。

**9、jdk 1.5引入了泛型,泛型用来解决什么问题?**

引入泛型后,如果明确设置了类型,则类型就是所设置的类型;如果没有设置类型,则默认类型为Object类。
(1)避免向下转型。

 (2)提高安全性:将运行期的错误转换到编译期。

10、数据库连接池是什么?

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

11、阐述jdbc操作数据库的步骤?

JDBC-数据库连接,是由一些类和接口构成的API,是J2SE的一部分,有java.sql、javax.sql包组成。下面看一下JDBC API与应用程序和数据库驱动及数据库之间的关系:
![file](http://wyz.wangyaozheng.top/wyz/article/20181225141326610.png)
可以看出JDBC是Sun公司为应用程序与数据库驱动之间提供的一组接口(规范)。数据库驱动是实现数据库操作的类,它并不由sun公司来实现,而是由具体的公司来根据sun提供的规范(JDBC)来制作。
操作数据库的步骤(以mySql为例)

 与ODBC类似,分为以下几步(2层JDBC体系结构为例):

  1.      注册驱动

  2.      建立连接

  3.      创建执行sql语句的对象

  4.      执行语句

  5.      处理执行结果

  6.      释放资源



 下面进行详解:

  1. 注册驱动

   常用的有3种方式:

   1)      直接注册驱动:

   DriverManager.registerDriver(com.mysql.jdbc.Driver);这种方式要求程序首先要引入驱动包,否则无法通过编译。而且它可能会造成DriverManager中产生两个一样的驱动,并对具体的驱动类产生依赖,所以不推荐使用。

   2)      键值对方式:

   System.setProperty(“jdbc.drivers”,”com.mysql.jdbc.Driver”);同时注册多个驱动则用冒号隔开。这种方式如果事先不引入驱动包的情况下能通过编译(因为操作的都为字符串,运行时肯定不行啦),所以虽然不会对具体的驱动类产生依赖,但注册不太方便,所以很少使用。

   3)      Class.forName方式(类似反射):

   Class.forName(“com.mysql.jdbc.Driver”); Class.forName函数的作用是根据类的名字将类装载到虚拟机中(并未实例化);这种方式也不会对具体的驱动类产生依赖,而且使用很方便,所以推荐使用。

  2. 建立连接

   Connection conn=DriverManager.getConnection(url,uid,pwd);

   url格式:JDBC:子协议:子名称//主机名:端口/数据库名?key=value&…

       例如:jdbc:mysql://localhost:8086/jdbc;uid和pwd也可以用key=value的方式告诉数据库。

            其它参数:如,userUnicode=true&characterEncoding=gbk

  3. 创建执行sql语句的对象

   这里有两个对象可以使用:Statement、PreparedStatement对象

   一般来说有参数的sql操作都用PreparedStatement对象,因为它有防止sql注入等优点。两者的区别这里不多介绍,创建语句:(假设conn为数据库连接对象)

   Statement st=conn.createStatement();

   PreparedStatement ps=conn.prepareStatement(strSql);

   可以看出在创建PreparedStatement对象时即需要指明要执行的sql语句,因为它会对sql语句进行预处理,例如进行一些防止sql注入的字符过滤等;而Statement则在执行sql动作时才指明sql语句。

  4. 执行语句(CURD)

   查询:st.executeQuery(strSql);或者ps. executeQuery();

   非查询(增、删、改):st.executeUpdate(strSql);或ps.executeUpdate();

  5. 处理执行结果

   查询:返回值用ResultSet接收,例:ResultSet rs=st.executeQuery(strsql)

   非查询(增、删、改):返回值为int

  6. 释放资源

   依次释放ResultSet、Statement(或PreparedStatement)、Connection对象,释放顺序与创建顺序相反(类似“栈”结构)。

   注意,Connection是非常稀有的资源,用完必须马上释放,它的使用原则是尽量晚的创建,尽量早的释放,以减少占用资源的时间。

13、数组Array和ArrayList的区别?什么时候使用Array而不是ArrayList?

Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。



ArrayList可以算是Array的加强版,(对array有所取舍的加强)。

另附分类比较:
存储内容比较:

Array数组可以包含基本类型和对象类型,
ArrayList却只能包含对象类型。
但是需要注意的是:Array数组在存放的时候一定是同种类型的元素。ArrayList就不一定了,因为ArrayList可以存储Object。

空间大小比较:

它的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。
ArrayList的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大约0.5倍的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。(比较麻烦的地方)。
  附上arraylist扩充机制:newCapacity=oldCapacity+(oldCapacity>>1)(注: >>1:右移1位,相当于除以2,例如10>>1 得到的就是5)但由于源码里(不再分析,这里简要略过)传过来的minCapcatiy的值是size+1,能够实现grow方法调用就肯定是(size+1)>elementData.length的情况,所以size就是初始最大容量或上一次扩容后达到的最大容量,所以才会进行扩容。因此,扩容后的大小应该是原来的1.5倍+1
方法上的比较: 
ArrayList作为Array的增强版,当然是在方法上比Array更多样化,比如添加全部addAll()、删除全部removeAll()、返回迭代器iterator()等。

适用场景: 
如果想要保存一些在整个程序运行期间都会存在而且不变的数据,我们可以将它们放进一个全局数组里,但是如果我们单纯只是想要以数组的形式保存数据,而不对数据进行增加等操作,只是方便我们进行查找的话,那么,我们就选择ArrayList。而且还有一个地方是必须知道的,就是如果我们需要对元素进行频繁的移动或删除,或者是处理的是超大量的数据,那么,使用ArrayList就真的不是一个好的选择,因为它的效率很低,使用数组进行这样的动作就很麻烦,那么,我们可以考虑选择LinkedList。

14、spring依赖注入有哪些方式?

1、set注入:
 这是一种简单的注入方式,首先新建一个名叫IOCMain的类,类中需要实例化一个IOCdependency的对象。然后定义一个IOCdependency的成员变量,并建立get和set方法。
private IOCdependency IOCdependency;
// 第一种方式,set方式
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }
public IOCdependency getIOCdependency() {
return IOCdependency;
}
public void showOk(){
IOCdependency.output();
}

随后编写Spring的配置文件applicationContext.xml。<bean>中的name为类的一个别名,而class为类的完整名称。

由于在IOCMain的类中存在IOCdependency属性,因此要在<bean>中设置属性<property>,name为属性的名称,
ref指向名为IOCdependency的bean
<!-- 第一种方法,set方法依赖注入配置 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--依赖注入,注入当前属性 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<bean name="IOCdependency" class="com.elish.model.IOCdependency"></bean>

2、构造器注入:
构造器注入指的是在类中构造带参数的构造方法实现类的注入,在这次的例子中就是在IOCMain的类中创建IOCdependency的构造方法,通过该构造方法实现注入,而不需要set函数。
// 第二种方式,构造器方式,在构造方法中调用IOCdepedency,达到注入的效果
      public IOCMain(IOCdependency iocdependency){
      this.IOCdependency=iocdependency; }

在配置文件中,不再用<property>标签,而是用<constructor-arg>标签代替,其中ref指向IOCdependency的bean,当存在多个参数时,有可能存在某些参数是同样类型的情况,为了确定参数的位置,可以为每个参数设置索引index,确定参数的位置
<!-- 第二种方法,构造器方法依赖注入配置 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--创建构造器注入,如果主类有带参的构造方法则需添加此配置 -->
<constructor-arg ref="IOCdependency" index="0"></constructor-arg>
</bean> 
<bean name="IOCdependency" class="com.elish.model.IOCdependency"></bean>

3、静态工厂的方式注入
通过建立静态工厂的方式进行注入,首先创建一个静态工厂IOCstaticFactory的类,然后在工厂类中创建getStaticFactory()的方法
public class IOCstaticFactory {
public static final IOCdependency getStaticFactory(){
return new IOCdependency();
}
}
在IOCMain中,创建与set方法注入相同的set方法。
// 第三种方式,静态工厂方式,在工厂类中返回静态IOCFactory对象
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }
与上面两个方法不同,这次在配置文件中不会直接定义IOCdependcy的bean,而是定义静态工厂IOCstaticFactory的bean,在这个bean中,需要配置factory-method="getStaticFactory"来指定调用哪个工厂方法。并在IOCMain的bean中定义指向静态工厂bean的<property><!-- 第三种方法,静态工厂方法 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--使用静态工厂的方法注入对象,对应下面的配置文件 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<bean name="IOCdependency" class="com.elish.model.IOCstaticFactory" factory-method="getStaticFactory"></bean>

4、动态工厂的方式注入

与静态工厂方式注入的方法不同,它需要先创建工厂类再调用方法
public class IOCFactory {
public IOCdependency getFactory(){
return new IOCdependency();
}
}

这里也需要set方法
// 第四种方式,实体工厂方式,在工厂类中返回实体IOCFactory对象
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }

与静态工厂的方法不同,这里需要定义IOCdependency的bean,并指定factory-bean和factory-method
<!-- 第四种方法,实体工厂方法 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!-- 使用实例工厂的方法注入对象,对应下面的配置文件 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<!-- 此处获取对象的方式是从工厂类中获取实例方法 -->
<bean name="IOCFactory" class="com.elish.model.IOCFactory"></bean>
<bean name="IOCdependency" factory-bean="IOCFactory"
factory-method="getFactory"></bean>

15、spring 支持的几种bean 作用域

Spring的Bean有以下五种作用域

singleton:SpringIOC容器只会创建该Bean的唯一实例;

prototype:每次请求都创建一个实例;

request:每次HTTP请求都会产生一个新的bean。需要注意的是,该作用域仅在基于Web的Spring ApplicationContext情形下有效,以下的session和global Session也是如此;

Session:每次会话创建一个实例;

global session:全局HttpSession中,容器会返回该bean的同一个实例。
正文到此结束
Loading...